diff --git a/.foreman b/.foreman deleted file mode 100644 index 87c3f5a1c158686373e3179b503b0a7b7987587b..0000000000000000000000000000000000000000 --- a/.foreman +++ /dev/null @@ -1 +0,0 @@ -port: 3000 diff --git a/.hound.yml b/.hound.yml deleted file mode 100644 index 3bde29fb2bf974a6345220ff6d7ac4247e1e4621..0000000000000000000000000000000000000000 --- a/.hound.yml +++ /dev/null @@ -1,4 +0,0 @@ -# Prefer single quotes -StringLiterals: - EnforcedStyle: single_quotes - Enabled: true diff --git a/.pkgr.yml b/.pkgr.yml deleted file mode 100644 index 8fc9fddf8f79d5f5dc391732879b307712d201cf..0000000000000000000000000000000000000000 --- a/.pkgr.yml +++ /dev/null @@ -1,37 +0,0 @@ -user: git -group: git -services: - - postgres -before_precompile: ./bin/pkgr_before_precompile.sh -targets: - debian-7: &wheezy - build_dependencies: - - libkrb5-dev - - libicu-dev - - cmake - - pkg-config - dependencies: - - libicu48 - - libpcre3 - - git - ubuntu-12.04: *wheezy - ubuntu-14.04: - build_dependencies: - - libkrb5-dev - - libicu-dev - - cmake - - pkg-config - dependencies: - - libicu52 - - libpcre3 - - git - centos-6: - build_dependencies: - - krb5-devel - - libicu-devel - - cmake - - pkgconfig - dependencies: - - libicu - - pcre - - git diff --git a/.rspec b/.rspec deleted file mode 100644 index 4e1e0d2f722485c7d284fb5cd7da855826e39b5a..0000000000000000000000000000000000000000 --- a/.rspec +++ /dev/null @@ -1 +0,0 @@ ---color diff --git a/.rubocop.yml b/.rubocop.yml deleted file mode 100644 index 03b78d6884016d3cca875d16414e521914703a73..0000000000000000000000000000000000000000 --- a/.rubocop.yml +++ /dev/null @@ -1,1006 +0,0 @@ -Style/AccessModifierIndentation: - Description: Check indentation of private/protected visibility modifiers. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#indent-public-private-protected' - Enabled: true - -Style/AccessorMethodName: - Description: Check the naming of accessor methods for get_/set_. - Enabled: false - -Style/Alias: - Description: 'Use alias_method instead of alias.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#alias-method' - Enabled: true - -Style/AlignArray: - Description: >- - Align the elements of an array literal if they span more than - one line. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#align-multiline-arrays' - Enabled: true - -Style/AlignHash: - Description: >- - Align the elements of a hash literal if they span more than - one line. - Enabled: true - -Style/AlignParameters: - Description: >- - Align the parameters of a method call if they span more - than one line. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-double-indent' - Enabled: false - -Style/AndOr: - Description: 'Use &&/|| instead of and/or.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-and-or-or' - Enabled: false - -Style/ArrayJoin: - Description: 'Use Array#join instead of Array#*.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#array-join' - Enabled: false - -Style/AsciiComments: - Description: 'Use only ascii symbols in comments.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-comments' - Enabled: true - -Style/AsciiIdentifiers: - Description: 'Use only ascii symbols in identifiers.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#english-identifiers' - Enabled: true - -Style/Attr: - Description: 'Checks for uses of Module#attr.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr' - Enabled: false - -Style/BeginBlock: - Description: 'Avoid the use of BEGIN blocks.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-BEGIN-blocks' - Enabled: true - -Style/BarePercentLiterals: - Description: 'Checks if usage of %() or %Q() matches configuration.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-q-shorthand' - Enabled: false - -Style/BlockComments: - Description: 'Do not use block comments.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-block-comments' - Enabled: false - -Style/BlockEndNewline: - Description: 'Put end statement of multiline block on its own line.' - Enabled: true - -Style/Blocks: - Description: >- - Avoid using {...} for multi-line blocks (multiline chaining is - always ugly). - Prefer {...} over do...end for single-line blocks. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks' - Enabled: true - -Style/BracesAroundHashParameters: - Description: 'Enforce braces style around hash parameters.' - Enabled: false - -Style/CaseEquality: - Description: 'Avoid explicit use of the case equality operator(===).' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-case-equality' - Enabled: false - -Style/CaseIndentation: - Description: 'Indentation of when in a case/when/[else/]end.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#indent-when-to-case' - Enabled: true - -Style/CharacterLiteral: - Description: 'Checks for uses of character literals.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-character-literals' - Enabled: true - -Style/ClassAndModuleCamelCase: - Description: 'Use CamelCase for classes and modules.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#camelcase-classes' - Enabled: true - -Style/ClassAndModuleChildren: - Description: 'Checks style of children classes and modules.' - Enabled: false - -Style/ClassCheck: - Description: 'Enforces consistent use of `Object#is_a?` or `Object#kind_of?`.' - Enabled: false - -Style/ClassMethods: - Description: 'Use self when defining module/class methods.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#def-self-singletons' - Enabled: false - -Style/ClassVars: - Description: 'Avoid the use of class variables.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-class-vars' - Enabled: true - -Style/ColonMethodCall: - Description: 'Do not use :: for method call.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#double-colons' - Enabled: false - -Style/CommentAnnotation: - Description: >- - Checks formatting of special comments - (TODO, FIXME, OPTIMIZE, HACK, REVIEW). - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#annotate-keywords' - Enabled: false - -Style/CommentIndentation: - Description: 'Indentation of comments.' - Enabled: true - -Style/ConstantName: - Description: 'Constants should use SCREAMING_SNAKE_CASE.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#screaming-snake-case' - Enabled: true - -Style/DefWithParentheses: - Description: 'Use def with parentheses when there are arguments.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens' - Enabled: false - -Style/DeprecatedHashMethods: - Description: 'Checks for use of deprecated Hash methods.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-key' - Enabled: false - -Style/Documentation: - Description: 'Document classes and non-namespace modules.' - Enabled: false - -Style/DotPosition: - Description: 'Checks the position of the dot in multi-line method calls.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains' - Enabled: false - -Style/DoubleNegation: - Description: 'Checks for uses of double negation (!!).' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-bang-bang' - Enabled: false - -Style/EachWithObject: - Description: 'Prefer `each_with_object` over `inject` or `reduce`.' - Enabled: false - -Style/ElseAlignment: - Description: 'Align elses and elsifs correctly.' - Enabled: true - -Style/EmptyElse: - Description: 'Avoid empty else-clauses.' - Enabled: false - -Style/EmptyLineBetweenDefs: - Description: 'Use empty lines between defs.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#empty-lines-between-methods' - Enabled: false - -Style/EmptyLines: - Description: "Don't use several empty lines in a row." - Enabled: false - -Style/EmptyLinesAroundAccessModifier: - Description: "Keep blank lines around access modifiers." - Enabled: false - -Style/EmptyLinesAroundBlockBody: - Description: "Keeps track of empty lines around block bodies." - Enabled: false - -Style/EmptyLinesAroundClassBody: - Description: "Keeps track of empty lines around class bodies." - Enabled: false - -Style/EmptyLinesAroundModuleBody: - Description: "Keeps track of empty lines around module bodies." - Enabled: false - -Style/EmptyLinesAroundMethodBody: - Description: "Keeps track of empty lines around method bodies." - Enabled: false - -Style/EmptyLiteral: - Description: 'Prefer literals to Array.new/Hash.new/String.new.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#literal-array-hash' - Enabled: false - -Style/EndBlock: - Description: 'Avoid the use of END blocks.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-END-blocks' - Enabled: false - -Style/EndOfLine: - Description: 'Use Unix-style line endings.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#crlf' - Enabled: false - -Style/EvenOdd: - Description: 'Favor the use of Fixnum#even? && Fixnum#odd?' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods' - Enabled: false - -Style/FileName: - Description: 'Use snake_case for source file names.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-files' - Enabled: false - -Style/FlipFlop: - Description: 'Checks for flip flops' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-flip-flops' - Enabled: false - -Style/For: - Description: 'Checks use of for or each in multiline loops.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-for-loops' - Enabled: false - -Style/FormatString: - Description: 'Enforce the use of Kernel#sprintf, Kernel#format or String#%.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#sprintf' - Enabled: false - -Style/GlobalVars: - Description: 'Do not introduce global variables.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#instance-vars' - Enabled: false - -Style/GuardClause: - Description: 'Check for conditionals that can be replaced with guard clauses' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals' - Enabled: false - -Style/HashSyntax: - Description: >- - Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax - { :a => 1, :b => 2 }. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-literals' - Enabled: true - -Style/IfUnlessModifier: - Description: >- - Favor modifier if/unless usage when you have a - single-line body. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier' - Enabled: false - -Style/IfWithSemicolon: - Description: 'Do not use if x; .... Use the ternary operator instead.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs' - Enabled: false - -Style/IndentationConsistency: - Description: 'Keep indentation straight.' - Enabled: true - -Style/IndentationWidth: - Description: 'Use 2 spaces for indentation.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation' - Enabled: true - -Style/IndentArray: - Description: >- - Checks the indentation of the first element in an array - literal. - Enabled: false - -Style/IndentHash: - Description: 'Checks the indentation of the first key in a hash literal.' - Enabled: false - -Style/InfiniteLoop: - Description: 'Use Kernel#loop for infinite loops.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#infinite-loop' - Enabled: false - -Style/Lambda: - Description: 'Use the new lambda literal syntax for single-line blocks.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#lambda-multi-line' - Enabled: false - -Style/LambdaCall: - Description: 'Use lambda.call(...) instead of lambda.(...).' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc-call' - Enabled: false - -Style/LeadingCommentSpace: - Description: 'Comments should start with a space.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-space' - Enabled: false - -Style/LineEndConcatenation: - Description: >- - Use \ instead of + or << to concatenate two string literals at - line end. - Enabled: false - -Style/MethodCallParentheses: - Description: 'Do not use parentheses for method calls with no arguments.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens' - Enabled: false - -Style/MethodDefParentheses: - Description: >- - Checks if the method definitions have or don't have - parentheses. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens' - Enabled: false - -Style/MethodName: - Description: 'Use the configured style when naming methods.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars' - Enabled: false - -Style/ModuleFunction: - Description: 'Checks for usage of `extend self` in modules.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#module-function' - Enabled: false - -Style/MultilineBlockChain: - Description: 'Avoid multi-line chains of blocks.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#single-line-blocks' - Enabled: false - -Style/MultilineBlockLayout: - Description: 'Ensures newlines after multiline block do statements.' - Enabled: true - -Style/MultilineIfThen: - Description: 'Do not use then for multi-line if/unless.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-then' - Enabled: false - -Style/MultilineOperationIndentation: - Description: >- - Checks indentation of binary operations that span more than - one line. - Enabled: false - -Style/MultilineTernaryOperator: - Description: >- - Avoid multi-line ?: (the ternary operator); - use if/unless instead. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-multiline-ternary' - Enabled: false - -Style/NegatedIf: - Description: >- - Favor unless over if for negative conditions - (or control flow or). - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#unless-for-negatives' - Enabled: false - -Style/NegatedWhile: - Description: 'Favor until over while for negative conditions.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#until-for-negatives' - Enabled: false - -Style/NestedTernaryOperator: - Description: 'Use one expression per branch in a ternary operator.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-ternary' - Enabled: true - -Style/Next: - Description: 'Use `next` to skip iteration instead of a condition at the end.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals' - Enabled: false - -Style/NilComparison: - Description: 'Prefer x.nil? to x == nil.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#predicate-methods' - Enabled: true - -Style/NonNilCheck: - Description: 'Checks for redundant nil checks.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-non-nil-checks' - Enabled: true - -Style/Not: - Description: 'Use ! instead of not.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bang-not-not' - Enabled: true - -Style/NumericLiterals: - Description: >- - Add underscores to large numeric literals to improve their - readability. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics' - Enabled: false - -Style/OneLineConditional: - Description: >- - Favor the ternary operator(?:) over - if/then/else/end constructs. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#ternary-operator' - Enabled: true - -Style/OpMethod: - Description: 'When defining binary operators, name the argument other.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#other-arg' - Enabled: false - -Style/ParenthesesAroundCondition: - Description: >- - Don't use parentheses around the condition of an - if/unless/while. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-parens-if' - Enabled: true - -Style/PercentLiteralDelimiters: - Description: 'Use `%`-literal delimiters consistently' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-literal-braces' - Enabled: false - -Style/PercentQLiterals: - Description: 'Checks if uses of %Q/%q match the configured preference.' - Enabled: false - -Style/PerlBackrefs: - Description: 'Avoid Perl-style regex back references.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers' - Enabled: false - -Style/PredicateName: - Description: 'Check the names of predicate methods.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark' - Enabled: false - -Style/Proc: - Description: 'Use proc instead of Proc.new.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#proc' - Enabled: false - -Style/RaiseArgs: - Description: 'Checks the arguments passed to raise/fail.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#exception-class-messages' - Enabled: false - -Style/RedundantBegin: - Description: "Don't use begin blocks when they are not needed." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#begin-implicit' - Enabled: false - -Style/RedundantException: - Description: "Checks for an obsolete RuntimeException argument in raise/fail." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-explicit-runtimeerror' - Enabled: false - -Style/RedundantReturn: - Description: "Don't use return where it's not required." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-explicit-return' - Enabled: true - -Style/RedundantSelf: - Description: "Don't use self where it's not needed." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-self-unless-required' - Enabled: false - -Style/RegexpLiteral: - Description: >- - Use %r for regular expressions matching more than - `MaxSlashes` '/' characters. - Use %r only for regular expressions matching more than - `MaxSlashes` '/' character. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-r' - Enabled: false - -Style/RescueModifier: - Description: 'Avoid using rescue in its modifier form.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-rescue-modifiers' - Enabled: false - -Style/SelfAssignment: - Description: >- - Checks for places where self-assignment shorthand should have - been used. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#self-assignment' - Enabled: false - -Style/Semicolon: - Description: "Don't use semicolons to terminate expressions." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-semicolon' - Enabled: false - -Style/SignalException: - Description: 'Checks for proper usage of fail and raise.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#fail-method' - Enabled: false - -Style/SingleLineBlockParams: - Description: 'Enforces the names of some block params.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#reduce-blocks' - Enabled: false - -Style/SingleLineMethods: - Description: 'Avoid single-line methods.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-single-line-methods' - Enabled: false - -Style/SingleSpaceBeforeFirstArg: - Description: >- - Checks that exactly one space is used between a method name - and the first argument for method calls without parentheses. - Enabled: false - -Style/SpaceAfterColon: - Description: 'Use spaces after colons.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' - Enabled: false - -Style/SpaceAfterComma: - Description: 'Use spaces after commas.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' - Enabled: false - -Style/SpaceAfterControlKeyword: - Description: 'Use spaces after if/elsif/unless/while/until/case/when.' - Enabled: false - -Style/SpaceAfterMethodName: - Description: >- - Do not put a space between a method name and the opening - parenthesis in a method definition. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces' - Enabled: false - -Style/SpaceAfterNot: - Description: Tracks redundant space after the ! operator. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-bang' - Enabled: false - -Style/SpaceAfterSemicolon: - Description: 'Use spaces after semicolons.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' - Enabled: false - -Style/SpaceBeforeBlockBraces: - Description: >- - Checks that the left block brace has or doesn't have space - before it. - Enabled: false - -Style/SpaceBeforeComma: - Description: 'No spaces before commas.' - Enabled: false - -Style/SpaceBeforeComment: - Description: >- - Checks for missing space between code and a comment on the - same line. - Enabled: false - -Style/SpaceBeforeSemicolon: - Description: 'No spaces before semicolons.' - Enabled: false - -Style/SpaceInsideBlockBraces: - Description: >- - Checks that block braces have or don't have surrounding space. - For blocks taking parameters, checks that the left brace has - or doesn't have trailing space. - Enabled: false - -Style/SpaceAroundEqualsInParameterDefault: - Description: >- - Checks that the equals signs in parameter default assignments - have or don't have surrounding space depending on - configuration. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-around-equals' - Enabled: false - -Style/SpaceAroundOperators: - Description: 'Use spaces around operators.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' - Enabled: false - -Style/SpaceBeforeModifierKeyword: - Description: 'Put a space before the modifier keyword.' - Enabled: false - -Style/SpaceInsideBrackets: - Description: 'No spaces after [ or before ].' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces' - Enabled: false - -Style/SpaceInsideHashLiteralBraces: - Description: "Use spaces inside hash literal braces - or don't." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-operators' - Enabled: true - -Style/SpaceInsideParens: - Description: 'No spaces after ( or before ).' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-spaces-braces' - Enabled: false - -Style/SpaceInsideRangeLiteral: - Description: 'No spaces inside range literals.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-space-inside-range-literals' - Enabled: false - -Style/SpecialGlobalVars: - Description: 'Avoid Perl-style global variables.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms' - Enabled: false - -Style/StringLiterals: - Description: 'Checks if uses of quotes match the configured preference.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#consistent-string-literals' - Enabled: false - -Style/StringLiteralsInInterpolation: - Description: >- - Checks if uses of quotes inside expressions in interpolated - strings match the configured preference. - Enabled: false - -Style/SymbolProc: - Description: 'Use symbols as procs instead of blocks when possible.' - Enabled: false - -Style/Tab: - Description: 'No hard tabs.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#spaces-indentation' - Enabled: true - -Style/TrailingBlankLines: - Description: 'Checks trailing blank lines and final newline.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#newline-eof' - Enabled: true - -Style/TrailingComma: - Description: 'Checks for trailing comma in parameter lists and literals.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas' - Enabled: false - -Style/TrailingWhitespace: - Description: 'Avoid trailing whitespace.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-trailing-whitespace' - Enabled: false - -Style/TrivialAccessors: - Description: 'Prefer attr_* methods to trivial readers/writers.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#attr_family' - Enabled: false - -Style/UnlessElse: - Description: >- - Do not use unless with else. Rewrite these with the positive - case first. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-else-with-unless' - Enabled: false - -Style/UnneededCapitalW: - Description: 'Checks for %W when interpolation is not needed.' - Enabled: false - -Style/UnneededPercentQ: - Description: 'Checks for %q/%Q when single quotes or double quotes would do.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-q' - Enabled: false - -Style/UnneededPercentX: - Description: 'Checks for %x when `` would do.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-x' - Enabled: false - -Style/VariableInterpolation: - Description: >- - Don't interpolate global, instance and class variables - directly in strings. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#curlies-interpolate' - Enabled: false - -Style/VariableName: - Description: 'Use the configured style when naming variables.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars' - Enabled: false - -Style/WhenThen: - Description: 'Use when x then ... for one-line cases.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#one-line-cases' - Enabled: false - -Style/WhileUntilDo: - Description: 'Checks for redundant do after while or until.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-multiline-while-do' - Enabled: false - -Style/WhileUntilModifier: - Description: >- - Favor modifier while/until usage when you have a - single-line body. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#while-as-a-modifier' - Enabled: false - -Style/WordArray: - Description: 'Use %w or %W for arrays of words.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-w' - Enabled: false - -#################### Metrics ################################ - -Metrics/AbcSize: - Description: >- - A calculated magnitude based on number of assignments, - branches, and conditions. - Enabled: false - -Metrics/BlockNesting: - Description: 'Avoid excessive block nesting' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count' - Enabled: false - -Metrics/ClassLength: - Description: 'Avoid classes longer than 100 lines of code.' - Enabled: false - -Metrics/CyclomaticComplexity: - Description: >- - A complexity metric that is strongly correlated to the number - of test cases needed to validate a method. - Enabled: false - -Metrics/LineLength: - Description: 'Limit lines to 80 characters.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#80-character-limits' - Enabled: false - -Metrics/MethodLength: - Description: 'Avoid methods longer than 10 lines of code.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#short-methods' - Enabled: false - -Metrics/ParameterLists: - Description: 'Avoid parameter lists longer than three or four parameters.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#too-many-params' - Enabled: false - -Metrics/PerceivedComplexity: - Description: >- - A complexity metric geared towards measuring complexity for a - human reader. - Enabled: false - -#################### Lint ################################ -### Warnings - -Lint/AmbiguousOperator: - Description: >- - Checks for ambiguous operators in the first argument of a - method invocation without parentheses. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-as-args' - Enabled: false - -Lint/AmbiguousRegexpLiteral: - Description: >- - Checks for ambiguous regexp literals in the first argument of - a method invocation without parenthesis. - Enabled: false - -Lint/AssignmentInCondition: - Description: "Don't use assignment in conditions." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition' - Enabled: false - -Lint/BlockAlignment: - Description: 'Align block ends correctly.' - Enabled: false - -Lint/ConditionPosition: - Description: >- - Checks for condition placed in a confusing position relative to - the keyword. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#same-line-condition' - Enabled: false - -Lint/Debugger: - Description: 'Check for debugger calls.' - Enabled: false - -Lint/DefEndAlignment: - Description: 'Align ends corresponding to defs correctly.' - Enabled: false - -Lint/DeprecatedClassMethods: - Description: 'Check for deprecated class method calls.' - Enabled: false - -Lint/ElseLayout: - Description: 'Check for odd code arrangement in an else block.' - Enabled: false - -Lint/EmptyEnsure: - Description: 'Checks for empty ensure block.' - Enabled: false - -Lint/EmptyInterpolation: - Description: 'Checks for empty string interpolation.' - Enabled: false - -Lint/EndAlignment: - Description: 'Align ends correctly.' - Enabled: false - -Lint/EndInMethod: - Description: 'END blocks should not be placed inside method definitions.' - Enabled: false - -Lint/EnsureReturn: - Description: 'Do not use return in an ensure block.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-return-ensure' - Enabled: false - -Lint/Eval: - Description: 'The use of eval represents a serious security risk.' - Enabled: false - -Lint/HandleExceptions: - Description: "Don't suppress exception." - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions' - Enabled: false - -Lint/InvalidCharacterLiteral: - Description: >- - Checks for invalid character literals with a non-escaped - whitespace character. - Enabled: false - -Lint/LiteralInCondition: - Description: 'Checks of literals used in conditions.' - Enabled: false - -Lint/LiteralInInterpolation: - Description: 'Checks for literals used in interpolation.' - Enabled: false - -Lint/Loop: - Description: >- - Use Kernel#loop with break rather than begin/end/until or - begin/end/while for post-loop tests. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#loop-with-break' - Enabled: false - -Lint/ParenthesesAsGroupedExpression: - Description: >- - Checks for method calls with a space before the opening - parenthesis. - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#parens-no-spaces' - Enabled: true - -Lint/RequireParentheses: - Description: >- - Use parentheses in the method call to avoid confusion - about precedence. - Enabled: false - -Lint/RescueException: - Description: 'Avoid rescuing the Exception class.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-blind-rescues' - Enabled: false - -Lint/ShadowingOuterLocalVariable: - Description: >- - Do not use the same name as outer local variable - for block arguments or block local variables. - Enabled: false - -Lint/SpaceBeforeFirstArg: - Description: >- - Put a space between a method name and the first argument - in a method call without parentheses. - Enabled: false - -Lint/StringConversionInInterpolation: - Description: 'Checks for Object#to_s usage in string interpolation.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-to-s' - Enabled: false - -Lint/UnderscorePrefixedVariableName: - Description: 'Do not use prefix `_` for a variable that is used.' - Enabled: true - -Lint/UnusedBlockArgument: - Description: 'Checks for unused block arguments.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars' - Enabled: false - -Lint/UnusedMethodArgument: - Description: 'Checks for unused method arguments.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars' - Enabled: false - -Lint/UnreachableCode: - Description: 'Unreachable code.' - Enabled: false - -Lint/UselessAccessModifier: - Description: 'Checks for useless access modifiers.' - Enabled: false - -Lint/UselessAssignment: - Description: 'Checks for useless assignment to a local variable.' - StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars' - Enabled: false - -Lint/UselessComparison: - Description: 'Checks for comparison of something with itself.' - Enabled: false - -Lint/UselessElseWithoutRescue: - Description: 'Checks for useless `else` in `begin..end` without `rescue`.' - Enabled: false - -Lint/UselessSetterCall: - Description: 'Checks for useless setter call to a local variable.' - Enabled: false - -Lint/Void: - Description: 'Possible use of operator/literal/variable in void context.' - Enabled: false - -##################### Rails ################################## - -Rails/ActionFilter: - Description: 'Enforces consistent use of action filter methods.' - Enabled: false - -Rails/DefaultScope: - Description: 'Checks if the argument passed to default_scope is a block.' - Enabled: false - -Rails/Delegate: - Description: 'Prefer delegate method for delegations.' - Enabled: false - -Rails/HasAndBelongsToMany: - Description: 'Prefer has_many :through to has_and_belongs_to_many.' - Enabled: true - -Rails/Output: - Description: 'Checks for calls to puts, print, etc.' - Enabled: true - -Rails/ReadWriteAttribute: - Description: >- - Checks for read_attribute(:attr) and - write_attribute(:attr, val). - Enabled: false - -Rails/ScopeArgs: - Description: 'Checks the arguments of ActiveRecord scopes.' - Enabled: false - -Rails/Validation: - Description: 'Use validates :attribute, hash of validations.' - Enabled: false - - -# Exclude some of GitLab files -# -# -AllCops: - RunRailsCops: true - Exclude: - - 'spec/**/*' - - 'features/**/*' - - 'vendor/**/*' - - 'db/**/*' - - 'tmp/**/*' - - 'bin/**/*' - - 'lib/backup/**/*' - - 'lib/tasks/**/*' - - 'lib/email_validator.rb' - - 'lib/gitlab/upgrader.rb' - - 'lib/gitlab/seeder.rb' diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 399088bf465606fc2257b2741338f95e9c790390..0000000000000000000000000000000000000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.1.6 diff --git a/.simplecov b/.simplecov deleted file mode 100644 index d979288df44bfa11d3bbc74b52bae975631a4dbf..0000000000000000000000000000000000000000 --- a/.simplecov +++ /dev/null @@ -1,4 +0,0 @@ -# .simplecov -SimpleCov.start 'rails' do - merge_timeout 3600 -end diff --git a/.teatro.yml b/.teatro.yml deleted file mode 100644 index 3005436198154fbc3f812f0b51a26500d37391b7..0000000000000000000000000000000000000000 --- a/.teatro.yml +++ /dev/null @@ -1,8 +0,0 @@ -stage: - before: - - cp config/gitlab.teatro.yml config/gitlab.yml - - mkdir /apps/gitlab-satellites - - mkdir /apps/repositories - - database: - - RAILS_ENV=development force=yes bundle exec rake db:create gitlab:setup \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 3165b7379d3285e6e3c066bf29f4cc9e974ba5b0..0000000000000000000000000000000000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,179 +0,0 @@ -# Contribute to GitLab - -Thank you for your interest in contributing to GitLab. -This guide details how contribute to GitLab in a way that is efficient for everyone. -If you have read this guide and want to know how the GitLab core-team operates please see [the GitLab contributing process](PROCESS.md). - -## Contributor license agreement - -By submitting code as an individual you agree to the [individual contributor license agreement](doc/legal/individual_contributor_license_agreement.md). By submitting code as an entity you agree to the [corporate contributor license agreement](doc/legal/corporate_contributor_license_agreement.md). - -## Security vulnerability disclosure - -Please report suspected security vulnerabilities in private to support@gitlab.com, also see the [disclosure section on the GitLab.com website](http://about.gitlab.com/disclosure/). Please do NOT create publicly viewable issues for suspected security vulnerabilities. - -## Closing policy for issues and merge requests - -GitLab is a popular open source project and the capacity to deal with issues and merge requests is limited. Out of respect for our volunteers, issues and merge requests not in line with the guidelines listed in this document may be closed without notice. - -Please treat our volunteers with courtesy and respect, it will go a long way towards getting your issue resolved. - -Issues and merge requests should be in English and contain appropriate language for audiences of all ages. - -## Helping others - -Please help other GitLab users when you can. -The channnels people will reach out on can be found on the [getting help page](https://about.gitlab.com/getting-help/). -Sign up for the mailinglist, answer GitLab questions on StackOverflow or respond in the irc channel. -You can also sign up on [CodeTriage](http://www.codetriage.com/gitlabhq/gitlabhq) to help with one issue every day. - -## Issue tracker - -To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://about.gitlab.com/subscription/) and [consulting services](http://about.gitlab.com/consultancy/) are available from [GitLab.com](http://about.gitlab.com/). - -The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious errors in the latest [stable or development release of GitLab](MAINTENANCE.md). If something is wrong but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request. When submitting an issue please conform to the issue submission guidelines listed below. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue. - -Issues can be filed either at [gitlab.com](https://gitlab.com/gitlab-org/gitlab-ce/issues) or [github.com](https://github.com/gitlabhq/gitlabhq/issues). - -Do not use the issue tracker for feature requests. We have a specific [feature request forum](http://feedback.gitlab.com) for this purpose. Please keep feature requests as small and simple as possible, complex ones might be edited to make them small and simple. - -Please send a merge request with a tested solution or a merge request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there. - -### Issue tracker guidelines - -**[Search the issues](https://gitlab.com/gitlab-org/gitlab-ce/issues)** for similar entries before submitting your own, there's a good chance somebody else had the same issue. Show your support with `:+1:` and/or join the discussion. Please submit issues in the following format (as the first post): - -1. **Summary:** Summarize your issue in one sentence (what goes wrong, what did you expect to happen) -1. **Steps to reproduce:** How can we reproduce the issue -1. **Expected behavior:** Describe your issue in detail -1. **Observed behavior** -1. **Relevant logs and/or screenshots:** Please use code blocks (\`\`\`) to format console output, logs, and code as it's very hard to read otherwise. -1. **Output of checks** - * Results of GitLab [Application Check](doc/install/installation.md#check-application-status) (`sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true`); we will only investigate if the tests are passing - * Version of GitLab you are running; we will only investigate issues in the latest stable and development releases as per the [maintenance policy](MAINTENANCE.md) - * Add the last commit SHA-1 of the GitLab version you used to replicate the issue (obtainable from the help page) - * Describe your setup (use relevant parts from `sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`) -1. **Possible fixes**: If you can, link to the line of code that might be responsible for the problem - -## Merge requests - -We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a merge request for are listed with the [status 'accepting merge requests' on our feature request forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. If you want to add a new feature that is not marked it is best to first create a feedback issue (if there isn't one already) and leave a comment asking for it to be marked accepting merge requests. Please include screenshots or wireframes if the feature will also change the UI. - -Merge requests can be filed either at [gitlab.com](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests) or [github.com](https://github.com/gitlabhq/gitlabhq/pulls). - -If you are new to GitLab development (or web development in general), search for the label `easyfix` ([gitlab.com](https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=easyfix), [github](https://github.com/gitlabhq/gitlabhq/labels/easyfix)). Those are issues easy to fix, marked by the GitLab core-team. If you are unsure how to proceed but want to help, mention one of the core-team members to give you a hint. - -To start with GitLab download the [GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit) and see [Development section](doc/development/README.md) in the help file. - -### Merge request guidelines - -If you can, please submit a merge request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. In general bug fixes that include a regression test are merged quickly while new features without proper tests are least likely to receive timely feedback. The workflow to make a merge request is as follows: - -1. Fork the project on GitLab Cloud -1. Create a feature branch -1. Write [tests](https://gitlab.com/gitlab-org/gitlab-development-kit#running-the-tests) and code -1. Add your changes to the [CHANGELOG](CHANGELOG) -1. If you are changing the README, some documentation or other things which have no effect on the tests, add `[ci skip]` somewhere in the commit message -1. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits) -1. Push the commit to your fork -1. Submit a merge request (MR) to the master branch -1. The MR title should describe the change you want to make -1. The MR description should give a motive for your change and the method you used to achieve it -1. If the MR changes the UI it should include before and after screenshots -1. If the MR changes CSS classes please include the list of affected pages `grep css-class ./app -R` -1. Link relevant [issues](https://gitlab.com/gitlab-org/gitlab-ce/issues) and/or [feature requests](http://feedback.gitlab.com/) from the merge request description and leave a comment on them with a link back to the MR -1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submission -1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md). -1. Also have a look at the [shell command guidelines](doc/development/shell_commands.md) if your code reads or opens files, or handles paths to files on disk. - -The **official merge window** is in the beginning of the month from the 1st to the 7th day of the month. The best time to submit a MR and get feedback fast. Before this time the GitLab B.V. team is still dealing with work that is created by the monthly release such as assisting subscribers with upgrade issues, the release of Enterprise Edition and the upgrade of GitLab Cloud. After the 7th it is already getting closer to the release date of the next version. This means there is less time to fix the issues created by merging large new features. - -Please keep the change in a single MR **as small as possible**. If you want to contribute a large feature think very hard what the minimum viable change is. Can you split functionality? Can you only submit the backend/API code? Can you start with a very simple UI? Can you do part of the refactor? The increased reviewability of small MR's that leads to higher code quality is more important to us than having a minimal commit log. The smaller a MR is the more likely it is it will be merged (quickly), after that you can send more MR's to enhance it. - -For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). If you would like quick feedback on your merge request feel free to mention one of the Merge Marshalls of [the core-team](https://about.gitlab.com/core-team/). Please ensure that your merge request meets the contribution acceptance criteria. - -## Definition of done - -If you contribute to GitLab please know that changes involve more than just code. -We have the following [definition of done](http://guide.agilealliance.org/guide/definition-of-done.html). -Please ensure you support the feature you contribute through all of these steps. - -1. Description explaning the relevancy (see following item) -1. Working and clean code that is commented where needed -1. Unit and integration tests that pass on the CI server -1. Documented in the /doc directory -1. Changelog entry added -1. Reviewed and any concerns are addressed -1. Merged by the project lead -1. Added to the release blog article -1. Added to [the website](https://gitlab.com/gitlab-com/www-gitlab-com/) if relevant -1. Community questions answered -1. Answers to questions radiated (in docs/wiki/etc.) - -If you add a dependency in GitLab (such as an operating system package) please consider updating the following and note the applicability of each in your merge request: - -1. Note the addition in the release blog post (create one if it doesn't exist yet) https://gitlab.com/gitlab-com/www-gitlab-com/merge_requests/ -1. Upgrade guide, for example https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/7.5-to-7.6.md -1. Upgrader https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/upgrader.md#2-run-gitlab-upgrade-tool -1. Installation guide https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies -1. GitLab Development Kit https://gitlab.com/gitlab-org/gitlab-development-kit -1. Test suite https://gitlab.com/gitlab-org/gitlab-ci/blob/master/doc/examples/configure_a_runner_to_run_the_gitlab_ce_test_suite.md -1. Omnibus package creator https://gitlab.com/gitlab-org/omnibus-gitlab - -## Merge request description format - -1. What does this MR do? -1. Are there points in the code the reviewer needs to double check? -1. Why was this MR needed? -1. What are the relevant issue numbers / [Feature requests](http://feedback.gitlab.com/)? -1. Screenshots (if relevant) - -## Contribution acceptance criteria - -1. The change is as small as possible (see the above paragraph for details) -1. Include proper tests and make all tests pass (unless it contains a test exposing a bug in existing code) -1. All tests have to pass, if you suspect a failing CI build is unrelated to your contribution ask for tests to be restarted. See [the CI setup document](http://doc.gitlab.com/ce/development/ci_setup.html) on who you can ask for test restart. -1. Initially contains a single commit (please use `git rebase -i` to squash commits) -1. Can merge without problems (if not please merge `master`, never rebase commits pushed to the remote server) -1. Does not break any existing functionality -1. Fixes one specific issue or implements one specific feature (do not combine things, send separate merge requests if needed) -1. Migrations should do only one thing (eg: either create a table, move data to a new table or remove an old table) to aid retrying on failure -1. Keeps the GitLab code base clean and well structured -1. Contains functionality we think other users will benefit from too -1. Doesn't add configuration options since they complicate future changes -1. Changes after submitting the merge request should be in separate commits (no squashing). You will be asked to squash when the review is over, before merging. -1. It conforms to the following style guides. - If your change touches a line that does not follow the style, - modify the entire line to follow it. This prevents linting tools from generating warnings. - Don't touch neighbouring lines. As an exception, automatic mass refactoring modifications - may leave style non-compliant. - -## Style guides - -1. [Ruby](https://github.com/bbatsov/ruby-style-guide). - Important sections include [Source Code Layout](https://github.com/bbatsov/ruby-style-guide#source-code-layout) - and [Naming](https://github.com/bbatsov/ruby-style-guide#naming). Use: - - multi-line method chaining style **Option B**: dot `.` on previous line - - string literal quoting style **Option A**: single quoted by default -1. [Rails](https://github.com/bbatsov/rails-style-guide) -1. [Testing](https://github.com/thoughtbot/guides/tree/master/style#testing) -1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style#coffeescript) -1. [Shell commands](doc/development/shell_commands.md) created by GitLab contributors to enhance security -1. [Markdown](http://www.cirosantilli.com/markdown-styleguide) -1. Interface text should be written subjectively instead of objectively. It should be the gitlab core team addressing a person. It should be written in present time and never use past tense (has been/was). For example instead of "prohibited this user from being saved due to the following errors:" the text should be "sorry, we could not create your account because:". Also these [excellent writing guidelines](https://github.com/NARKOZ/guides#writing). - -This is also the style used by linting tools such as [RuboCop](https://github.com/bbatsov/rubocop), [PullReview](https://www.pullreview.com/) and [Hound CI](https://houndci.com). - -## Code of conduct -As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. - -Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. - -Instances of abusive, harassing, or otherwise unacceptable behavior can be -reported by emailing contact@gitlab.com - -This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/) diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION deleted file mode 100644 index 097a15a2af39df14efb57a9212fc648b52746783..0000000000000000000000000000000000000000 --- a/GITLAB_SHELL_VERSION +++ /dev/null @@ -1 +0,0 @@ -2.6.2 diff --git a/Guardfile b/Guardfile deleted file mode 100644 index 68ac3232b099fdbedc643caee894c50ec83f922f..0000000000000000000000000000000000000000 --- a/Guardfile +++ /dev/null @@ -1,27 +0,0 @@ -# A sample Guardfile -# More info at https://github.com/guard/guard#readme - -guard 'rspec', cmd: "spring rspec", all_on_start: false, all_after_pass: false do - watch(%r{^spec/.+_spec\.rb$}) - watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } - watch(%r{^lib/api/(.+)\.rb$}) { |m| "spec/requests/api/#{m[1]}_spec.rb" } - watch('spec/spec_helper.rb') { "spec" } - - # Rails example - watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } - watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } - watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } - watch(%r{^spec/support/(.+)\.rb$}) { "spec" } - watch('config/routes.rb') { "spec/routing" } - watch('app/controllers/application_controller.rb') { "spec/controllers" } - - # Capybara request specs - watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" } -end - -guard 'spinach', command_prefix: 'spring' do - watch(%r|^features/(.*)\.feature|) - watch(%r|^features/steps/(.*)([^/]+)\.rb|) do |m| - "features/#{m[1]}#{m[2]}.feature" - end -end diff --git a/LICENSE b/LICENSE deleted file mode 100644 index d8cb29f36384fe739136ce15c79f41eb1ef45247..0000000000000000000000000000000000000000 --- a/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2011-2015 GitLab B.V. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/MAINTENANCE.md b/MAINTENANCE.md deleted file mode 100644 index d3d36670693aa4c9b5b51a44e37542b077d2c9cd..0000000000000000000000000000000000000000 --- a/MAINTENANCE.md +++ /dev/null @@ -1,15 +0,0 @@ -# GitLab Maintenance Policy - -GitLab is a fast moving and evolving project. We currently don't have the resources to support many releases concurrently. We support exactly one stable release at any given time. - -GitLab follows the [Semantic Versioning](http://semver.org/) for its releases: `(Major).(Minor).(Patch)` in a [pragmatic way](https://gist.github.com/jashkenas/cbd2b088e20279ae2c8e). - -- **Major version**: Whenever there is something significant or any backwards incompatible changes are introduced to the public API. -- **Minor version**: When new, backwards compatible functionality is introduced to the public API or a minor feature is introduced, or when a set of smaller features is rolled out. -- **Patch number**: When backwards compatible bug fixes are introduced that fix incorrect behavior. - -The current stable release will receive security patches and bug fixes (eg. `5.0` -> `5.0.1`). Feature releases will mark the next supported stable release where the minor version is increased numerically by increments of one (eg. `5.0 -> 5.1`). - -We encourage everyone to run the latest stable release to ensure that you can easily upgrade to the most secure and feature rich GitLab experience. In order to make sure you can easily run the most recent stable release, we are working hard to keep the update process simple and reliable. - -More information about the release procedures can be found in the doc/release directory. diff --git a/PROCESS.md b/PROCESS.md deleted file mode 100644 index 1b6b3e7d32d053ac6124be3c1637b3f8db12c204..0000000000000000000000000000000000000000 --- a/PROCESS.md +++ /dev/null @@ -1,113 +0,0 @@ -# GitLab Contributing Process - -## Purpose of describing the contributing process - -Below we describe the contributing process to GitLab for two reasons. So that contributors know what to expect from maintainers (possible responses, friendly treatment, etc.). And so that maintainers know what to expect from contributors (use the latest version, ensure that the issue is addressed, friendly treatment, etc.). - -## Common actions - -### Issue team -- Looks for issues without [workflow labels](#how-we-handle-issues) and triages issue -- Closes invalid issues with a comment (duplicates, [feature requests](#feature-requests), [fixed in newer version](#issue-fixed-in-newer-version), [issue report for old version](#issue-report-for-old-version), not a problem in GitLab, etc.) -- Asks for feedback from issue reporter ([invalid issue reports](#improperly-formatted-issue), [format code](#code-format), etc.) -- Monitors all issues for feedback (but especially ones commented on since automatically watching them) -- Closes issues with no feedback from the reporter for two weeks - -### Merge marshal - -- Responds to merge requests the issue team mentions them in and monitors for new merge requests -- Provides feedback to the merge request submitter to improve the merge request (style, tests, etc.) -- Mark merge requests 'ready-for-merge' when they meet the contribution guidelines -- Mention developer(s) based on the [list of members and their specialities](https://about.gitlab.com/core-team/) -- Closes merge requests with no feedback from the reporter for two weeks - -## Priorities of the issue team - -1. Mentioning people (critical) -1. Workflow labels (normal) -1. Functional labels (minor) -1. Assigning issues (avoid if possible) - -## Mentioning people - -The most important thing is making sure valid issues receive feedback from the development team. Therefore the priority is mentioning developers that can help on those issue. Please select someone with relevant experience from [GitLab core team](https://about.gitlab.com/core-team/). If there is nobody mentioned with that expertise look in the commit history for the affected files to find someone. Avoid mentioning the lead developer, this is the person that is least likely to give a timely response. If the involvement of the lead developer is needed the other core team members will mention this person. - -## Workflow labels - -Workflow labels are purposely not very detailed since that would be hard to keep updated as you would need to re-evaluate them after every comment. We optionally use functional labels on demand when want to group related issues to get an overview (for example all issues related to RVM, to tackle them in one go) and to add details to the issue. - -- *Awaiting feedback*: Feedback pending from the reporter -- *Awaiting confirmation of fix*: The issue should already be solved in **master** (generally you can avoid this workflow item and just close the issue right away) -- *Attached MR*: There is a MR attached and the discussion should happen there - - We need to let issues stay in sync with the MR's. We can do this with a "Closing #XXXX" or "Fixes #XXXX" comment in the MR. We can't close the issue when there is a merge request because sometimes a MR is not good and we just close the MR, then the issue must stay. -- *Awaiting developer action/feedback*: Issue needs to be fixed or clarified by a developer - -## Functional labels - -These labels describe what development specialities are involved such as: PostgreSQL, UX, LDAP. - -## Assigning issues - -If an issue is complex and needs the attention of a specific person, assignment is a good option but assigning issues might discourage other people from contributing to that issue. We need all the contributions we can get so this should never be discouraged. Also, an assigned person might not have time for a few weeks, so others should feel free to takeover. - -## Label colors - -- Light orange `#fef2c0`: workflow labels for issue team members (awaiting feedback, awaiting confirmation of fix) -- Bright orange `#eb6420`: workflow labels for core team members (attached MR, awaiting developer action/feedback) -- Light blue `#82C5FF`: functional labels -- Green labels `#009800`: issues that can generally be ignored. For example, issues given the following labels normally can be closed immediately: - - Feature request (see copy & paste response: [Feature requests](#feature-requests)) - - Support (see copy & paste response: [Support requests and configuration questions](#support-requests-and-configuration-questions) - -## Be kind - -Be kind to people trying to contribute. Be aware that people may be a non-native English speaker, they might not understand things or they might be very sensitive as to how you word things. Use Emoji to express your feelings (heart, star, smile, etc.). Some good tips about giving feedback to merge requests is in the [Thoughtbot code review guide](https://github.com/thoughtbot/guides/tree/master/code-review). - -## Copy & paste responses - -### Improperly formatted issue - -Thanks for the issue report. Please reformat your issue to conform to the issue tracker guidelines found in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). - -### Feature requests - -Thank you for your interest in improving GitLab. We don't use the issue tracker for feature requests. Things that are wrong but are not a regression compared to older versions of GitLab are considered feature requests and not issues. Please use the \[feature request forum\]\(http://feedback.gitlab.com/) for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. - -### Issue report for old version - -Thanks for the issue report but we only support issues for the latest stable version of GitLab. I'm closing this issue but if you still experience this problem in the latest stable version, please open a new issue (but also reference the old issue(s)). Make sure to also include the necessary debugging information conforming to the issue tracker guidelines found in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). - -### Support requests and configuration questions - -Thanks for your interest in GitLab. We don't use the issue tracker for support requests and configuration questions. Please use the \[support forum\]\(https://groups.google.com/forum/#!forum/gitlabhq), \[Stack Overflow\]\(http://stackoverflow.com/questions/tagged/gitlab), the #gitlab IRC channel on Freenode or the http://about.gitlab.com paid services for this purpose. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. - -### Code format - -Please use ``` to format console output, logs, and code as it's very hard to read otherwise. - -### Issue fixed in newer version - -Thanks for the issue report. This issue has already been fixed in newer versions of GitLab. Due to the size of this project and our limited resources we are only able to support the latest stable release as outlined in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker). In order to get this bug fix and enjoy many new features please \[upgrade\]\(https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update). If you still experience issues at that time please open a new issue following our issue tracker guidelines found in the \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). - -### Improperly formatted merge request - -Thanks for your interest in improving the GitLab codebase! Please update your merge request according to the \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#pull-request-guidelines). - -### Inactivity close of an issue - -It's been at least 2 weeks (and a new release) since we heard from you. I'm closing this issue but if you still experience this problem, please open a new issue (but also reference the old issue(s)). Make sure to also include the necessary debugging information conforming to the issue tracker guidelines found in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#issue-tracker-guidelines). - -### Inactivity close of a merge request - -This merge request has been closed because a request for more information has not been reacted to for more than 2 weeks. If you respond and conform to the merge request guidelines in our \[contributing guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#pull-requests) we will reopen this merge request. - -### Accepting merge requests - -Is there a request on [the feature request forum](http://feedback.gitlab.com/forums/176466-general) that is similar to this? If so, can you make a comment with a link to it? Please be aware that new functionality that is not marked [accepting merge/pull requests](http://feedback.gitlab.com/forums/176466-general/status/796455) on the forum might not make it into GitLab. You might be asked to make changes and even after implementing them your feature might still be declined. If you want to reduce the chance of this happening please have a discussion in the forum first. - -### Only accepting merge requests with green tests - -We can only accept a merge request if all the tests are green. I've just -restarted the build. When the tests are still not passing after this restart and -you're sure that is does not have anything to do with your code changes, please -rebase with master to see if that solves the issue. diff --git a/Procfile b/Procfile deleted file mode 100644 index 799b92729fa95aa90cc480ef9a01d7e6ae3b00db..0000000000000000000000000000000000000000 --- a/Procfile +++ /dev/null @@ -1,2 +0,0 @@ -web: bundle exec unicorn_rails -p ${PORT:="3000"} -E ${RAILS_ENV:="development"} -c ${UNICORN_CONFIG:="config/unicorn.rb"} -worker: bundle exec sidekiq -q post_receive -q mailer -q archive_repo -q system_hook -q project_web_hook -q gitlab_shell -q common -q default diff --git a/README.md b/README.md deleted file mode 100644 index 0563ceca4097c2ed5be75da2bf8177946a736bdd..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# ![logo](https://about.gitlab.com/images/gitlab_logo.png) GitLab - -## Open source software to collaborate on code - -![Animated screenshots](https://about.gitlab.com/images/animated/compiled.gif) - -- Manage Git repositories with fine grained access controls that keep your code secure -- Perform code reviews and enhance collaboration with merge requests -- Each project can also have an issue tracker and a wiki -- Used by more than 100,000 organizations, GitLab is the most popular solution to manage Git repositories on-premises -- Completely free and open source (MIT Expat license) -- Powered by [Ruby on Rails](https://github.com/rails/rails) - -## Editions - -There are two editions of GitLab. -*GitLab [Community Edition](https://about.gitlab.com/features/) (CE)* is available without any costs under an MIT license. - -*GitLab Enterprise Edition (EE)* includes [extra features](https://about.gitlab.com/features/#compare) that are most useful for organizations with more than 100 users. -To get access to the EE and support please [become a subscriber](https://about.gitlab.com/pricing/). - -## Canonical source - -The source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/) and there are mirrors to make [contributing](CONTRIBUTING.md) as easy as possible. - -## Code status - -- [![build status](https://ci.gitlab.org/projects/1/status.png?ref=master)](https://ci.gitlab.org/projects/1?ref=master) on ci.gitlab.org (master branch) - -- [![Build Status](https://semaphoreapp.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/243338/badge.png)](https://semaphoreapp.com/gitlabhq/gitlabhq) - -- [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq) - -- [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master) - -## Website - -On [about.gitlab.com](https://about.gitlab.com/) you can find more information about: - -- [Subscriptions](https://about.gitlab.com/subscription/) -- [Consultancy](https://about.gitlab.com/consultancy/) -- [Community](https://about.gitlab.com/community/) -- [Hosted GitLab.com](https://about.gitlab.com/gitlab-com/) use GitLab as a free service -- [GitLab Enterprise Edition](https://about.gitlab.com/gitlab-ee/) with additional features aimed at larger organizations. -- [GitLab CI](https://about.gitlab.com/gitlab-ci/) a continuous integration (CI) server that is easy to integrate with GitLab. - -## Requirements - -GitLab requires the following software: - -- Ubuntu/Debian/CentOS/RHEL -- Ruby (MRI) 2.0 or 2.1 -- Git 1.7.10+ -- Redis 2.0+ -- MySQL or PostgreSQL - -Please see the [requirements documentation](doc/install/requirements.md) for system requirements and more information about the supported operating systems. - -## Installation - -The recommended way to install GitLab is using the provided [Omnibus packages](https://about.gitlab.com/downloads/). Compared to an installation from source, this is faster and less error prone. Just select your operating system, download the respective package (Debian or RPM) and install it using the system's package manager. - -There are various other options to install GitLab, please refer to the [installation page on the GitLab website](https://about.gitlab.com/installation/) for more information. - -You can access a new installation with the login **`root`** and password **`5iveL!fe`**, after login you are required to set a unique password. - -## Third-party applications - -There are a lot of [third-party applications integrating with GitLab](https://about.gitlab.com/applications/). These include GUI Git clients, mobile applications and API wrappers for various languages. - -## GitLab release cycle - -Since 2011 a minor or major version of GitLab is released on the 22nd of every month. Patch and security releases are published when needed. New features are detailed on the [blog](https://about.gitlab.com/blog/) and in the [changelog](CHANGELOG). For more information about the release process see the [release documentation](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/release). Features that will likely be in the next releases can be found on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457). - -## Upgrading - -For updating the Omnibus installation please see the [update documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md). For installations from source there is an [upgrader script](doc/update/upgrader.md) and there are [upgrade guides](doc/update) detailing all necessary commands to migrate to the next version. - -## Install a development environment - -To work on GitLab itself, we recommend setting up your development environment with [the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit). -If you do not use the GitLab Development Kit you need to install and setup all the dependencies yourself, this is a lot of work and error prone. -One small thing you also have to do when installing it yourself is to copy the example development unicorn configuration file: - - cp config/unicorn.rb.example.development config/unicorn.rb - -Instructions on how to start GitLab and how to run the tests can be found in the [development section of the GitLab Development Kit](https://gitlab.com/gitlab-org/gitlab-development-kit#development). - -## Documentation - -All documentation can be found on [doc.gitlab.com/ce/](http://doc.gitlab.com/ce/). - -## Getting help - -Please see [Getting help for GitLab](https://about.gitlab.com/getting-help/) on our website for the many options to get help. - -## Is it any good? - -[Yes](https://news.ycombinator.com/item?id=3067434) - -## Is it awesome? - -Thanks for [asking this question](https://twitter.com/supersloth/status/489462789384056832) Joshua. -[These people](https://twitter.com/gitlab/favorites) seem to like it. diff --git a/Rakefile b/Rakefile deleted file mode 100644 index 35b2f05cbb4566b71b34554cf184a9d0bd9d46d6..0000000000000000000000000000000000000000 --- a/Rakefile +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env rake -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. - -require File.expand_path('../config/application', __FILE__) - -Gitlab::Application.load_tasks diff --git a/VERSION b/VERSION index bdc6df1ef36240b103f4247c6e3e1b9b493faf62..5306ee61e007b66d7477dcac875a1b7376a35626 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.10.0.rc4 \ No newline at end of file +7.10.0.rc5 \ No newline at end of file diff --git a/app/assets/images/authbuttons/bitbucket_64.png b/app/assets/images/authbuttons/bitbucket_64.png deleted file mode 100644 index 4b90a57bc7de93163275f99ea2971e2740af98af..0000000000000000000000000000000000000000 Binary files a/app/assets/images/authbuttons/bitbucket_64.png and /dev/null differ diff --git a/app/assets/images/authbuttons/github_64.png b/app/assets/images/authbuttons/github_64.png deleted file mode 100644 index dc7c03d10052a596f062207ae0fd8e9cf384b2aa..0000000000000000000000000000000000000000 Binary files a/app/assets/images/authbuttons/github_64.png and /dev/null differ diff --git a/app/assets/images/authbuttons/gitlab_64.png b/app/assets/images/authbuttons/gitlab_64.png deleted file mode 100644 index 31281a194441d4e23bb691de89110c6097021ac9..0000000000000000000000000000000000000000 Binary files a/app/assets/images/authbuttons/gitlab_64.png and /dev/null differ diff --git a/app/assets/images/authbuttons/google_64.png b/app/assets/images/authbuttons/google_64.png deleted file mode 100644 index 94a0e089c6efe07dcb50af341d51c2d13b689639..0000000000000000000000000000000000000000 Binary files a/app/assets/images/authbuttons/google_64.png and /dev/null differ diff --git a/app/assets/images/authbuttons/twitter_64.png b/app/assets/images/authbuttons/twitter_64.png deleted file mode 100644 index 5c9f14cb0771005efaa2ed050560298aa03131b3..0000000000000000000000000000000000000000 Binary files a/app/assets/images/authbuttons/twitter_64.png and /dev/null differ diff --git a/app/assets/images/bg-header.png b/app/assets/images/bg-header.png deleted file mode 100644 index 639271c6fafc58a2007f22478ba2d52e57c2a2ee..0000000000000000000000000000000000000000 Binary files a/app/assets/images/bg-header.png and /dev/null differ diff --git a/app/assets/images/bg_fallback.png b/app/assets/images/bg_fallback.png deleted file mode 100644 index e5fe659ba63db076784a420b69bf188d898ef52f..0000000000000000000000000000000000000000 Binary files a/app/assets/images/bg_fallback.png and /dev/null differ diff --git a/app/assets/images/brand_logo.png b/app/assets/images/brand_logo.png deleted file mode 100644 index 9c564bb61411bf4f0dec3e21aa86848ac70cbcb8..0000000000000000000000000000000000000000 Binary files a/app/assets/images/brand_logo.png and /dev/null differ diff --git a/app/assets/images/chosen-sprite.png b/app/assets/images/chosen-sprite.png deleted file mode 100644 index 3d936b07d443fb420a71cac72750537bb54ad2cd..0000000000000000000000000000000000000000 Binary files a/app/assets/images/chosen-sprite.png and /dev/null differ diff --git a/app/assets/images/dark-scheme-preview.png b/app/assets/images/dark-scheme-preview.png deleted file mode 100644 index 2ef58e52549c6315b66a6dc960e4603de1c00d4b..0000000000000000000000000000000000000000 Binary files a/app/assets/images/dark-scheme-preview.png and /dev/null differ diff --git a/app/assets/images/diff_note_add.png b/app/assets/images/diff_note_add.png deleted file mode 100644 index 0084422e3303593e2f067c7de013413f393b0f88..0000000000000000000000000000000000000000 Binary files a/app/assets/images/diff_note_add.png and /dev/null differ diff --git a/app/assets/images/favicon.ico b/app/assets/images/favicon.ico deleted file mode 100644 index bfb74960c480e6cb14f1d38437303af6b375ccaf..0000000000000000000000000000000000000000 Binary files a/app/assets/images/favicon.ico and /dev/null differ diff --git a/app/assets/images/gitorious-logo-black.png b/app/assets/images/gitorious-logo-black.png deleted file mode 100644 index 78f17a9af79dc2395acd9bcc2a391589dd6b6ed8..0000000000000000000000000000000000000000 Binary files a/app/assets/images/gitorious-logo-black.png and /dev/null differ diff --git a/app/assets/images/gitorious-logo-blue.png b/app/assets/images/gitorious-logo-blue.png deleted file mode 100644 index 4962cffba3153927ddd8cd5ff295fe4ca142bfa8..0000000000000000000000000000000000000000 Binary files a/app/assets/images/gitorious-logo-blue.png and /dev/null differ diff --git a/app/assets/images/icon-link.png b/app/assets/images/icon-link.png deleted file mode 100644 index 60021d5ac47686cce70570d22bad6670082caf56..0000000000000000000000000000000000000000 Binary files a/app/assets/images/icon-link.png and /dev/null differ diff --git a/app/assets/images/icon-search.png b/app/assets/images/icon-search.png deleted file mode 100644 index 3c1c146541d456a042db5768154a307b9b535e9d..0000000000000000000000000000000000000000 Binary files a/app/assets/images/icon-search.png and /dev/null differ diff --git a/app/assets/images/icon_sprite.png b/app/assets/images/icon_sprite.png deleted file mode 100644 index 2e7a5023398e7aa1d2794755af4f90d59b431919..0000000000000000000000000000000000000000 Binary files a/app/assets/images/icon_sprite.png and /dev/null differ diff --git a/app/assets/images/images.png b/app/assets/images/images.png deleted file mode 100644 index ad146246caf907144b468a121ef9524ba8ec3c74..0000000000000000000000000000000000000000 Binary files a/app/assets/images/images.png and /dev/null differ diff --git a/app/assets/images/logo-white.png b/app/assets/images/logo-white.png deleted file mode 100644 index 917bcfcb7e750f8426dd79912ca525dc65183a56..0000000000000000000000000000000000000000 Binary files a/app/assets/images/logo-white.png and /dev/null differ diff --git a/app/assets/images/monokai-scheme-preview.png b/app/assets/images/monokai-scheme-preview.png deleted file mode 100644 index fbb339c6a9170de79c5fee8fc2a5abd6a785f4e7..0000000000000000000000000000000000000000 Binary files a/app/assets/images/monokai-scheme-preview.png and /dev/null differ diff --git a/app/assets/images/move.png b/app/assets/images/move.png deleted file mode 100644 index 6a0567f8f2534837e7280dd41e4bf4b98725a3bf..0000000000000000000000000000000000000000 Binary files a/app/assets/images/move.png and /dev/null differ diff --git a/app/assets/images/no_avatar.png b/app/assets/images/no_avatar.png deleted file mode 100644 index 8287acbce13e32d0823c8f5fd449099c1c61d6cd..0000000000000000000000000000000000000000 Binary files a/app/assets/images/no_avatar.png and /dev/null differ diff --git a/app/assets/images/no_group_avatar.png b/app/assets/images/no_group_avatar.png deleted file mode 100644 index bfb31bb2184f6895c55c3027ddf9e357170bc338..0000000000000000000000000000000000000000 Binary files a/app/assets/images/no_group_avatar.png and /dev/null differ diff --git a/app/assets/images/onion_skin_sprites.gif b/app/assets/images/onion_skin_sprites.gif deleted file mode 100644 index 337aa1bfb632ff492b0a24ffe652ca5ab46f6ffa..0000000000000000000000000000000000000000 Binary files a/app/assets/images/onion_skin_sprites.gif and /dev/null differ diff --git a/app/assets/images/progress_bar.gif b/app/assets/images/progress_bar.gif deleted file mode 100644 index c3d43fa40b2fd90186d22f8a82bdc4673d8ab904..0000000000000000000000000000000000000000 Binary files a/app/assets/images/progress_bar.gif and /dev/null differ diff --git a/app/assets/images/slider_handles.png b/app/assets/images/slider_handles.png deleted file mode 100644 index 884378ec96a20c1cb2a419e1dc1aa68ab9d85c15..0000000000000000000000000000000000000000 Binary files a/app/assets/images/slider_handles.png and /dev/null differ diff --git a/app/assets/images/solarized-dark-scheme-preview.png b/app/assets/images/solarized-dark-scheme-preview.png deleted file mode 100644 index 7ed7336896b1daa3d06b3f304931bc2006a3b145..0000000000000000000000000000000000000000 Binary files a/app/assets/images/solarized-dark-scheme-preview.png and /dev/null differ diff --git a/app/assets/images/solarized-light-scheme-preview.png b/app/assets/images/solarized-light-scheme-preview.png deleted file mode 100644 index c50db75449b974294a612f3215a673c7c2217f80..0000000000000000000000000000000000000000 Binary files a/app/assets/images/solarized-light-scheme-preview.png and /dev/null differ diff --git a/app/assets/images/swipemode_sprites.gif b/app/assets/images/swipemode_sprites.gif deleted file mode 100644 index b010b4e4482760d5e144d93c2b6c76fa4f981438..0000000000000000000000000000000000000000 Binary files a/app/assets/images/swipemode_sprites.gif and /dev/null differ diff --git a/app/assets/images/switch_icon.png b/app/assets/images/switch_icon.png deleted file mode 100644 index c6b6c8d9521f64b00990ca5352c8ce269e9a3e4a..0000000000000000000000000000000000000000 Binary files a/app/assets/images/switch_icon.png and /dev/null differ diff --git a/app/assets/images/trans_bg.gif b/app/assets/images/trans_bg.gif deleted file mode 100644 index 1a1c9c15ec71a58db869578399068cf313c51599..0000000000000000000000000000000000000000 Binary files a/app/assets/images/trans_bg.gif and /dev/null differ diff --git a/app/assets/images/white-scheme-preview.png b/app/assets/images/white-scheme-preview.png deleted file mode 100644 index fc4c40b9227cced4692d9c3f0b3e09d62894fe3e..0000000000000000000000000000000000000000 Binary files a/app/assets/images/white-scheme-preview.png and /dev/null differ diff --git a/app/assets/javascripts/activities.js.coffee b/app/assets/javascripts/activities.js.coffee deleted file mode 100644 index 777c62dc1b7773254cab7bfbe588166832a944dc..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/activities.js.coffee +++ /dev/null @@ -1,29 +0,0 @@ -class @Activities - constructor: -> - Pager.init 20, true - $(".event_filter_link").bind "click", (event) => - event.preventDefault() - @toggleFilter($(event.currentTarget)) - @reloadActivities() - - reloadActivities: -> - $(".content_list").html '' - Pager.init 20, true - - - toggleFilter: (sender) -> - sender.parent().toggleClass "active" - event_filters = $.cookie("event_filter") - filter = sender.attr("id").split("_")[0] - if event_filters - event_filters = event_filters.split(",") - else - event_filters = new Array() - - index = event_filters.indexOf(filter) - if index is -1 - event_filters.push filter - else - event_filters.splice index, 1 - - $.cookie "event_filter", event_filters.join(","), { path: '/' } diff --git a/app/assets/javascripts/admin.js.coffee b/app/assets/javascripts/admin.js.coffee deleted file mode 100644 index bcb2e6df7c01450cc9bccd1a530f8811d2ae6976..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/admin.js.coffee +++ /dev/null @@ -1,53 +0,0 @@ -class @Admin - constructor: -> - $('input#user_force_random_password').on 'change', (elem) -> - elems = $('#user_password, #user_password_confirmation') - - if $(@).attr 'checked' - elems.val('').attr 'disabled', true - else - elems.removeAttr 'disabled' - - $('body').on 'click', '.js-toggle-colors-link', (e) -> - e.preventDefault() - $('.js-toggle-colors-link').hide() - $('.js-toggle-colors-container').show() - - $('input#broadcast_message_color').on 'input', -> - previewColor = $('input#broadcast_message_color').val() - $('div.broadcast-message-preview').css('background-color', previewColor) - - $('input#broadcast_message_font').on 'input', -> - previewColor = $('input#broadcast_message_font').val() - $('div.broadcast-message-preview').css('color', previewColor) - - $('textarea#broadcast_message_message').on 'input', -> - previewMessage = $('textarea#broadcast_message_message').val() - $('div.broadcast-message-preview span').text(previewMessage) - - $('.log-tabs a').click (e) -> - e.preventDefault() - $(this).tab('show') - - $('.log-bottom').click (e) -> - e.preventDefault() - visible_log = $(".file-content:visible") - visible_log.animate({ scrollTop: visible_log.find('ol').height() }, "fast") - - modal = $('.change-owner-holder') - - $('.change-owner-link').bind "click", (e) -> - e.preventDefault() - $(this).hide() - modal.show() - - $('.change-owner-cancel-link').bind "click", (e) -> - e.preventDefault() - modal.hide() - $('.change-owner-link').show() - - $('li.project_member').bind 'ajax:success', -> - Turbolinks.visit(location.href) - - $('li.group_member').bind 'ajax:success', -> - Turbolinks.visit(location.href) diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee deleted file mode 100644 index 9e5d594c861d6867308d9c47b571795fe5f51efd..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/api.js.coffee +++ /dev/null @@ -1,49 +0,0 @@ -@Api = - groups_path: "/api/:version/groups.json" - group_path: "/api/:version/groups/:id.json" - namespaces_path: "/api/:version/namespaces.json" - - group: (group_id, callback) -> - url = Api.buildUrl(Api.group_path) - url = url.replace(':id', group_id) - - $.ajax( - url: url - data: - private_token: gon.api_token - dataType: "json" - ).done (group) -> - callback(group) - - # Return groups list. Filtered by query - # Only active groups retrieved - groups: (query, skip_ldap, callback) -> - url = Api.buildUrl(Api.groups_path) - - $.ajax( - url: url - data: - private_token: gon.api_token - search: query - per_page: 20 - dataType: "json" - ).done (groups) -> - callback(groups) - - # Return namespaces list. Filtered by query - namespaces: (query, callback) -> - url = Api.buildUrl(Api.namespaces_path) - - $.ajax( - url: url - data: - private_token: gon.api_token - search: query - per_page: 20 - dataType: "json" - ).done (namespaces) -> - callback(namespaces) - - buildUrl: (url) -> - url = gon.relative_url_root + url if gon.relative_url_root? - return url.replace(':version', gon.api_version) diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee deleted file mode 100644 index fda142293bc9b42daab5866d9c52f38339a8409e..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/application.js.coffee +++ /dev/null @@ -1,194 +0,0 @@ -# This is a manifest file that'll be compiled into including all the files listed below. -# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically -# be included in the compiled file accessible from http://example.com/assets/application.js -# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -# the compiled file. -# -#= require jquery -#= require jquery.ui.all -#= require jquery_ujs -#= require jquery.cookie -#= require jquery.endless-scroll -#= require jquery.highlight -#= require jquery.history -#= require jquery.waitforimages -#= require jquery.atwho -#= require jquery.scrollTo -#= require jquery.blockUI -#= require jquery.turbolinks -#= require jquery.sticky-kit.min -#= require turbolinks -#= require autosave -#= require bootstrap -#= require select2 -#= require raphael -#= require g.raphael-min -#= require g.bar-min -#= require chart-lib.min -#= require branch-graph -#= require ace/ace -#= require ace/ext-searchbox -#= require d3 -#= require underscore -#= require nprogress -#= require nprogress-turbolinks -#= require dropzone -#= require mousetrap -#= require mousetrap/pause -#= require shortcuts -#= require shortcuts_navigation -#= require shortcuts_dashboard_navigation -#= require shortcuts_issueable -#= require shortcuts_network -#= require cal-heatmap -#= require_tree . - -window.slugify = (text) -> - text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase() - -window.ajaxGet = (url) -> - $.ajax({type: "GET", url: url, dataType: "script"}) - -window.showAndHide = (selector) -> - -window.split = (val) -> - return val.split( /,\s*/ ) - -window.extractLast = (term) -> - return split( term ).pop() - -window.rstrip = (val) -> - return if val then val.replace(/\s+$/, '') else val - -# Disable button if text field is empty -window.disableButtonIfEmptyField = (field_selector, button_selector) -> - field = $(field_selector) - closest_submit = field.closest('form').find(button_selector) - - closest_submit.disable() if rstrip(field.val()) is "" - - field.on 'input', -> - if rstrip($(@).val()) is "" - closest_submit.disable() - else - closest_submit.enable() - -# Disable button if any input field with given selector is empty -window.disableButtonIfAnyEmptyField = (form, form_selector, button_selector) -> - closest_submit = form.find(button_selector) - updateButtons = -> - filled = true - form.find('input').filter(form_selector).each -> - filled = rstrip($(this).val()) != "" || !$(this).attr('required') - - if filled - closest_submit.enable() - else - closest_submit.disable() - - updateButtons() - form.keyup(updateButtons) - -window.sanitize = (str) -> - return str.replace(/<(?:.|\n)*?>/gm, '') - -window.linkify = (str) -> - exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig - return str.replace(exp,"$1") - -window.simpleFormat = (str) -> - linkify(sanitize(str).replace(/\n/g, '
')) - -window.unbindEvents = -> - $(document).unbind('scroll') - $(document).off('scroll') - -window.shiftWindow = -> - scrollBy 0, -50 - -document.addEventListener("page:fetch", unbindEvents) - -# Scroll the window to avoid the topnav bar -# https://github.com/twitter/bootstrap/issues/1768 -if location.hash - setTimeout shiftWindow, 1 -window.addEventListener "hashchange", shiftWindow - -$ -> - # Click a .one_click_select field, select the contents - $(".one_click_select").on 'click', -> $(@).select() - - $('.remove-row').bind 'ajax:success', -> - $(this).closest('li').fadeOut() - - # Initialize select2 selects - $('select.select2').select2(width: 'resolve', dropdownAutoWidth: true) - - # Close select2 on escape - $('.js-select2').bind 'select2-close', -> - setTimeout ( -> - $('.select2-container-active').removeClass('select2-container-active') - $(':focus').blur() - ), 1 - - # Initialize tooltips - $('.has_tooltip').tooltip() - - # Bottom tooltip - $('.has_bottom_tooltip').tooltip(placement: 'bottom') - - # Form submitter - $('.trigger-submit').on 'change', -> - $(@).parents('form').submit() - - $("abbr.timeago").timeago() - $('.js-timeago').timeago() - - # Flash - if (flash = $(".flash-container")).length > 0 - flash.click -> $(@).fadeOut() - flash.show() - - # Disable form buttons while a form is submitting - $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> - buttons = $('[type="submit"]', @) - - switch e.type - when 'ajax:beforeSend', 'submit' - buttons.disable() - else - buttons.enable() - - # Show/Hide the profile menu when hovering the account box - $('.account-box').hover -> $(@).toggleClass('hover') - - # Commit show suppressed diff - $(".diff-content").on "click", ".supp_diff_link", -> - $(@).next('table').show() - $(@).remove() - - # Show/hide comments on diff - $("body").on "click", ".js-toggle-diff-comments", (e) -> - $(@).toggleClass('active') - $(@).closest(".diff-file").find(".notes_holder").toggle() - e.preventDefault() - - $(document).on "click", '.js-confirm-danger', (e) -> - e.preventDefault() - btn = $(e.target) - text = btn.data("confirm-danger-message") - form = btn.closest("form") - new ConfirmDangerModal(form, text) - - new Aside() - -(($) -> - # Disable an element and add the 'disabled' Bootstrap class - $.fn.extend disable: -> - $(@).attr('disabled', 'disabled').addClass('disabled') - - # Enable an element and remove the 'disabled' Bootstrap class - $.fn.extend enable: -> - $(@).removeAttr('disabled').removeClass('disabled') - -)(jQuery) diff --git a/app/assets/javascripts/aside.js.coffee b/app/assets/javascripts/aside.js.coffee deleted file mode 100644 index 854731019443e3ea1d49e73a3fa5a12e5fc00185..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/aside.js.coffee +++ /dev/null @@ -1,17 +0,0 @@ -class @Aside - constructor: -> - $(document).off "click", "a.show-aside" - $(document).on "click", 'a.show-aside', (e) -> - e.preventDefault() - btn = $(e.currentTarget) - icon = btn.find('i') - console.log('1') - - if icon.hasClass('fa-angle-left') - btn.parent().find('section').hide() - btn.parent().find('aside').fadeIn() - icon.removeClass('fa-angle-left').addClass('fa-angle-right') - else - btn.parent().find('aside').hide() - btn.parent().find('section').fadeIn() - icon.removeClass('fa-angle-right').addClass('fa-angle-left') diff --git a/app/assets/javascripts/autosave.js.coffee b/app/assets/javascripts/autosave.js.coffee deleted file mode 100644 index 5d3fe81da74aefe071aaf29f905d29f39a898859..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/autosave.js.coffee +++ /dev/null @@ -1,39 +0,0 @@ -class @Autosave - constructor: (field, key) -> - @field = field - - key = key.join("/") if key.join? - @key = "autosave/#{key}" - - @field.data "autosave", this - - @restore() - - @field.on "input", => @save() - - restore: -> - return unless window.localStorage? - - try - text = window.localStorage.getItem @key - catch - return - - @field.val text if text?.length > 0 - @field.trigger "input" - - save: -> - return unless window.localStorage? - - text = @field.val() - if text?.length > 0 - try - window.localStorage.setItem @key, text - else - @reset() - - reset: -> - return unless window.localStorage? - - try - window.localStorage.removeItem @key diff --git a/app/assets/javascripts/behaviors/details_behavior.coffee b/app/assets/javascripts/behaviors/details_behavior.coffee deleted file mode 100644 index decab3e1bed29bc2c9f26804be2308f52298da34..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/behaviors/details_behavior.coffee +++ /dev/null @@ -1,15 +0,0 @@ -$ -> - $("body").on "click", ".js-details-target", -> - container = $(@).closest(".js-details-container") - container.toggleClass("open") - - # Show details content. Hides link after click. - # - # %div - # %a.js-details-expand - # %div.js-details-content - # - $("body").on "click", ".js-details-expand", (e) -> - $(@).next('.js-details-content').removeClass("hide") - $(@).hide() - e.preventDefault() diff --git a/app/assets/javascripts/behaviors/taskable.js.coffee b/app/assets/javascripts/behaviors/taskable.js.coffee deleted file mode 100644 index ddce71c18863eca382fe2d2322d5e6f35206a819..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/behaviors/taskable.js.coffee +++ /dev/null @@ -1,21 +0,0 @@ -window.updateTaskState = (taskableType) -> - objType = taskableType.data - isChecked = $(this).prop("checked") - if $(this).is(":checked") - stateEvent = "task_check" - else - stateEvent = "task_uncheck" - - taskableUrl = $("form.edit-" + objType).first().attr("action") - taskableNum = taskableUrl.match(/\d+$/) - taskNum = 0 - $("li.task-list-item input:checkbox").each( (index, e) => - if e == this - taskNum = index + 1 - ) - - $.ajax - type: "PATCH" - url: taskableUrl - data: objType + "[state_event]=" + stateEvent + - "&" + objType + "[task_num]=" + taskNum diff --git a/app/assets/javascripts/behaviors/toggler_behavior.coffee b/app/assets/javascripts/behaviors/toggler_behavior.coffee deleted file mode 100644 index 177b6918270dcc1a58851fc46f10dcb5aae2f06e..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/behaviors/toggler_behavior.coffee +++ /dev/null @@ -1,14 +0,0 @@ -$ -> - # Toggle button. Show/hide content inside parent container. - # Button does not change visibility. If button has icon - it changes chevron style. - # - # %div.js-toggle-container - # %a.js-toggle-button - # %div.js-toggle-content - # - $("body").on "click", ".js-toggle-button", (e) -> - $(@).find('i'). - toggleClass('fa fa-chevron-down'). - toggleClass('fa fa-chevron-up') - $(@).closest(".js-toggle-container").find(".js-toggle-content").toggle() - e.preventDefault() diff --git a/app/assets/javascripts/blob/blob.js.coffee b/app/assets/javascripts/blob/blob.js.coffee deleted file mode 100644 index 37a175fdbc725fdaceb0187ab73547063c0821bb..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/blob/blob.js.coffee +++ /dev/null @@ -1,73 +0,0 @@ -class @BlobView - constructor: -> - # handle multi-line select - handleMultiSelect = (e) -> - [ first_line, last_line ] = parseSelectedLines() - [ line_number ] = parseSelectedLines($(this).attr("id")) - hash = "L#{line_number}" - - if e.shiftKey and not isNaN(first_line) and not isNaN(line_number) - if line_number < first_line - last_line = first_line - first_line = line_number - else - last_line = line_number - - hash = if first_line == last_line then "L#{first_line}" else "L#{first_line}-#{last_line}" - - setHash(hash) - e.preventDefault() - - # See if there are lines selected - # "#L12" and "#L34-56" supported - highlightBlobLines = (e) -> - [ first_line, last_line ] = parseSelectedLines() - - unless isNaN first_line - $("#tree-content-holder .highlight .line").removeClass("hll") - $("#LC#{line}").addClass("hll") for line in [first_line..last_line] - $.scrollTo("#L#{first_line}", offset: -50) unless e? - - # parse selected lines from hash - # always return first and last line (initialized to NaN) - parseSelectedLines = (str) -> - first_line = NaN - last_line = NaN - hash = str || window.location.hash - - if hash isnt "" - matches = hash.match(/\#?L(\d+)(\-(\d+))?/) - first_line = parseInt(matches?[1]) - last_line = parseInt(matches?[3]) - last_line = first_line if isNaN(last_line) - - [ first_line, last_line ] - - setHash = (hash) -> - hash = hash.replace(/^\#/, "") - nodes = $("#" + hash) - # if any nodes are using this id, they must be temporarily changed - # also, add a temporary div at the top of the screen to prevent scrolling - if nodes.length > 0 - scroll_top = $(document).scrollTop() - nodes.attr("id", "") - tmp = $("
") - .css({ position: "absolute", visibility: "hidden", top: scroll_top + "px" }) - .attr("id", hash) - .appendTo(document.body) - - window.location.hash = hash - - # restore the nodes - if nodes.length > 0 - tmp.remove() - nodes.attr("id", hash) - - # initialize multi-line select - $("#tree-content-holder .line-numbers a[id^=L]").on("click", handleMultiSelect) - - # Highlight the correct lines on load - highlightBlobLines() - - # Highlight the correct lines when the hash part of the URL changes - $(window).on("hashchange", highlightBlobLines) diff --git a/app/assets/javascripts/blob/edit_blob.js.coffee b/app/assets/javascripts/blob/edit_blob.js.coffee deleted file mode 100644 index 2e91a06daa8b900eda0d91f1721ce26a30d842be..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/blob/edit_blob.js.coffee +++ /dev/null @@ -1,44 +0,0 @@ -class @EditBlob - constructor: (assets_path, mode)-> - ace.config.set "modePath", assets_path + '/ace' - ace.config.loadModule "ace/ext/searchbox" - if mode - ace_mode = mode - editor = ace.edit("editor") - editor.focus() - @editor = editor - - if ace_mode - editor.getSession().setMode "ace/mode/" + ace_mode - - disableButtonIfEmptyField "#commit_message", ".js-commit-button" - $(".js-commit-button").click -> - $("#file-content").val editor.getValue() - $(".file-editor form").submit() - return false - - editModePanes = $(".js-edit-mode-pane") - editModeLinks = $(".js-edit-mode a") - editModeLinks.click (event) -> - event.preventDefault() - currentLink = $(this) - paneId = currentLink.attr("href") - currentPane = editModePanes.filter(paneId) - editModeLinks.parent().removeClass "active hover" - currentLink.parent().addClass "active hover" - editModePanes.hide() - if paneId is "#preview" - currentPane.fadeIn 200 - $.post currentLink.data("preview-url"), - content: editor.getValue() - , (response) -> - currentPane.empty().append response - return - - else - currentPane.fadeIn 200 - editor.focus() - return - - editor: -> - return @editor diff --git a/app/assets/javascripts/blob/new_blob.js.coffee b/app/assets/javascripts/blob/new_blob.js.coffee deleted file mode 100644 index ab8f98715e86edf03dbc0d142e079958ae50d756..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/blob/new_blob.js.coffee +++ /dev/null @@ -1,21 +0,0 @@ -class @NewBlob - constructor: (assets_path, mode)-> - ace.config.set "modePath", assets_path + '/ace' - ace.config.loadModule "ace/ext/searchbox" - if mode - ace_mode = mode - editor = ace.edit("editor") - editor.focus() - @editor = editor - - if ace_mode - editor.getSession().setMode "ace/mode/" + ace_mode - - disableButtonIfEmptyField "#commit_message", ".js-commit-button" - $(".js-commit-button").click -> - $("#file-content").val editor.getValue() - $(".file-editor form").submit() - return false - - editor: -> - return @editor diff --git a/app/assets/javascripts/branch-graph.js.coffee b/app/assets/javascripts/branch-graph.js.coffee deleted file mode 100644 index 010a2b0e42b88588a704acaf488daee667f34e53..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/branch-graph.js.coffee +++ /dev/null @@ -1,340 +0,0 @@ -class @BranchGraph - constructor: (@element, @options) -> - @preparedCommits = {} - @mtime = 0 - @mspace = 0 - @parents = {} - @colors = ["#000"] - @offsetX = 150 - @offsetY = 20 - @unitTime = 30 - @unitSpace = 10 - @prev_start = -1 - @load() - - load: -> - $.ajax - url: @options.url - method: "get" - dataType: "json" - success: $.proxy((data) -> - $(".loading", @element).hide() - @prepareData data.days, data.commits - @buildGraph() - , this) - - prepareData: (@days, @commits) -> - @collectParents() - @graphHeight = $(@element).height() - @graphWidth = $(@element).width() - ch = Math.max(@graphHeight, @offsetY + @unitTime * @mtime + 150) - cw = Math.max(@graphWidth, @offsetX + @unitSpace * @mspace + 300) - @r = Raphael(@element.get(0), cw, ch) - @top = @r.set() - @barHeight = Math.max(@graphHeight, @unitTime * @days.length + 320) - - for c in @commits - c.isParent = true if c.id of @parents - @preparedCommits[c.id] = c - @markCommit(c) - - @collectColors() - - collectParents: -> - for c in @commits - @mtime = Math.max(@mtime, c.time) - @mspace = Math.max(@mspace, c.space) - for p in c.parents - @parents[p[0]] = true - @mspace = Math.max(@mspace, p[1]) - - collectColors: -> - k = 0 - while k < @mspace - @colors.push Raphael.getColor(.8) - # Skipping a few colors in the spectrum to get more contrast between colors - Raphael.getColor() - Raphael.getColor() - k++ - - buildGraph: -> - r = @r - cuday = 0 - cumonth = "" - - r.rect(0, 0, 40, @barHeight).attr fill: "#222" - r.rect(40, 0, 30, @barHeight).attr fill: "#444" - - for day, mm in @days - if cuday isnt day[0] - # Dates - r.text(55, @offsetY + @unitTime * mm, day[0]) - .attr( - font: "12px Monaco, monospace" - fill: "#BBB" - ) - cuday = day[0] - - if cumonth isnt day[1] - # Months - r.text(20, @offsetY + @unitTime * mm, day[1]) - .attr( - font: "12px Monaco, monospace" - fill: "#EEE" - ) - cumonth = day[1] - - @renderPartialGraph() - - @bindEvents() - - renderPartialGraph: -> - start = Math.floor((@element.scrollTop() - @offsetY) / @unitTime) - 10 - if start < 0 - isGraphEdge = true - start = 0 - end = start + 40 - if @commits.length < end - isGraphEdge = true - end = @commits.length - - if @prev_start == -1 or Math.abs(@prev_start - start) > 10 or isGraphEdge - i = start - - @prev_start = start - - while i < end - commit = @commits[i] - i += 1 - - if commit.hasDrawn isnt true - x = @offsetX + @unitSpace * (@mspace - commit.space) - y = @offsetY + @unitTime * commit.time - - @drawDot(x, y, commit) - - @drawLines(x, y, commit) - - @appendLabel(x, y, commit) - - @appendAnchor(x, y, commit) - - commit.hasDrawn = true - - @top.toFront() - - bindEvents: -> - element = @element - - $(element).scroll (event) => - @renderPartialGraph() - - scrollDown: => - @element.scrollTop @element.scrollTop() + 50 - @renderPartialGraph() - - scrollUp: => - @element.scrollTop @element.scrollTop() - 50 - @renderPartialGraph() - - scrollLeft: => - @element.scrollLeft @element.scrollLeft() - 50 - @renderPartialGraph() - - scrollRight: => - @element.scrollLeft @element.scrollLeft() + 50 - @renderPartialGraph() - - scrollBottom: => - @element.scrollTop @element.find('svg').height() - - scrollTop: => - @element.scrollTop 0 - - appendLabel: (x, y, commit) -> - return unless commit.refs - - r = @r - shortrefs = commit.refs - # Truncate if longer than 15 chars - shortrefs = shortrefs.substr(0, 15) + "…" if shortrefs.length > 17 - text = r.text(x + 4, y, shortrefs).attr( - "text-anchor": "start" - font: "10px Monaco, monospace" - fill: "#FFF" - title: commit.refs - ) - textbox = text.getBBox() - # Create rectangle based on the size of the textbox - rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr( - fill: "#000" - "fill-opacity": .5 - stroke: "none" - ) - triangle = r.path(["M", x - 5, y, "L", x - 15, y - 4, "L", x - 15, y + 4, "Z"]).attr( - fill: "#000" - "fill-opacity": .5 - stroke: "none" - ) - - label = r.set(rect, text) - label.transform(["t", -rect.getBBox().width - 15, 0]) - - # Set text to front - text.toFront() - - appendAnchor: (x, y, commit) -> - r = @r - top = @top - options = @options - anchor = r.circle(x, y, 10).attr( - fill: "#000" - opacity: 0 - cursor: "pointer" - ).click(-> - window.open options.commit_url.replace("%s", commit.id), "_blank" - ).hover(-> - @tooltip = r.commitTooltip(x + 5, y, commit) - top.push @tooltip.insertBefore(this) - , -> - @tooltip and @tooltip.remove() and delete @tooltip - ) - top.push anchor - - drawDot: (x, y, commit) -> - r = @r - r.circle(x, y, 3).attr( - fill: @colors[commit.space] - stroke: "none" - ) - - avatar_box_x = @offsetX + @unitSpace * @mspace + 10 - avatar_box_y = y - 10 - r.rect(avatar_box_x, avatar_box_y, 20, 20).attr( - stroke: @colors[commit.space] - "stroke-width": 2 - ) - r.image(gon.relative_url_root + commit.author.icon, avatar_box_x, avatar_box_y, 20, 20) - r.text(@offsetX + @unitSpace * @mspace + 35, y, commit.message.split("\n")[0]).attr( - "text-anchor": "start" - font: "14px Monaco, monospace" - ) - - drawLines: (x, y, commit) -> - r = @r - for parent, i in commit.parents - parentCommit = @preparedCommits[parent[0]] - parentY = @offsetY + @unitTime * parentCommit.time - parentX1 = @offsetX + @unitSpace * (@mspace - parentCommit.space) - parentX2 = @offsetX + @unitSpace * (@mspace - parent[1]) - - # Set line color - if parentCommit.space <= commit.space - color = @colors[commit.space] - - else - color = @colors[parentCommit.space] - - # Build line shape - if parent[1] is commit.space - offset = [0, 5] - arrow = "l-2,5,4,0,-2,-5,0,5" - - else if parent[1] < commit.space - offset = [3, 3] - arrow = "l5,0,-2,4,-3,-4,4,2" - - else - offset = [-3, 3] - arrow = "l-5,0,2,4,3,-4,-4,2" - - # Start point - route = ["M", x + offset[0], y + offset[1]] - - # Add arrow if not first parent - if i > 0 - route.push(arrow) - - # Circumvent if overlap - if commit.space isnt parentCommit.space or commit.space isnt parent[1] - route.push( - "L", parentX2, y + 10, - "L", parentX2, parentY - 5, - ) - - # End point - route.push("L", parentX1, parentY) - - r - .path(route) - .attr( - stroke: color - "stroke-width": 2) - - markCommit: (commit) -> - if commit.id is @options.commit_id - r = @r - x = @offsetX + @unitSpace * (@mspace - commit.space) - y = @offsetY + @unitTime * commit.time - r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr( - fill: "#000" - "fill-opacity": .5 - stroke: "none" - ) - # Displayed in the center - @element.scrollTop(y - @graphHeight / 2) - -Raphael::commitTooltip = (x, y, commit) -> - boxWidth = 300 - boxHeight = 200 - icon = @image(gon.relative_url_root + commit.author.icon, x, y, 20, 20) - nameText = @text(x + 25, y + 10, commit.author.name) - idText = @text(x, y + 35, commit.id) - messageText = @text(x, y + 50, commit.message) - textSet = @set(icon, nameText, idText, messageText).attr( - "text-anchor": "start" - font: "12px Monaco, monospace" - ) - nameText.attr( - font: "14px Arial" - "font-weight": "bold" - ) - - idText.attr fill: "#AAA" - @textWrap messageText, boxWidth - 50 - rect = @rect(x - 10, y - 10, boxWidth, 100, 4).attr( - fill: "#FFF" - stroke: "#000" - "stroke-linecap": "round" - "stroke-width": 2 - ) - tooltip = @set(rect, textSet) - rect.attr( - height: tooltip.getBBox().height + 10 - width: tooltip.getBBox().width + 10 - ) - - tooltip.transform ["t", 20, 20] - tooltip - -Raphael::textWrap = (t, width) -> - content = t.attr("text") - abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - t.attr text: abc - letterWidth = t.getBBox().width / abc.length - t.attr text: content - words = content.split(" ") - x = 0 - s = [] - - for word in words - if x + (word.length * letterWidth) > width - s.push "\n" - x = 0 - x += word.length * letterWidth - s.push word + " " - - t.attr text: s.join("") - b = t.getBBox() - h = Math.abs(b.y2) - Math.abs(b.y) + 1 - t.attr y: b.y + h diff --git a/app/assets/javascripts/calendar.js.coffee b/app/assets/javascripts/calendar.js.coffee deleted file mode 100644 index 44d75bd694f009aa8db8915c26179f1be2626f30..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/calendar.js.coffee +++ /dev/null @@ -1,38 +0,0 @@ -class @Calendar - options = - month: "short" - day: "numeric" - year: "numeric" - - constructor: (timestamps, starting_year, starting_month, calendar_activities_path) -> - cal = new CalHeatMap() - cal.init - itemName: ["contribution"] - data: timestamps - start: new Date(starting_year, starting_month) - domainLabelFormat: "%b" - id: "cal-heatmap" - domain: "month" - subDomain: "day" - range: 12 - tooltip: true - label: - position: "top" - legend: [ - 0 - 10 - 20 - 30 - ] - legendCellPadding: 3 - onClick: (date, count) -> - formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() - $.ajax - url: calendar_activities_path - data: - date: formated_date - cache: false - dataType: "html" - success: (data) -> - $(".user-calendar-activities").html data - diff --git a/app/assets/javascripts/commit.js.coffee b/app/assets/javascripts/commit.js.coffee deleted file mode 100644 index 0566e239191e2a57ff6628c69ee3d6f5d8d55b16..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/commit.js.coffee +++ /dev/null @@ -1,4 +0,0 @@ -class @Commit - constructor: -> - $('.files .diff-file').each -> - new CommitFile(this) diff --git a/app/assets/javascripts/commit/file.js.coffee b/app/assets/javascripts/commit/file.js.coffee deleted file mode 100644 index 83e793863b60623e06d5866d94ca54f2b958608a..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/commit/file.js.coffee +++ /dev/null @@ -1,5 +0,0 @@ -class @CommitFile - - constructor: (file) -> - if $('.image', file).length - new ImageFile(file) diff --git a/app/assets/javascripts/commit/image-file.js.coffee b/app/assets/javascripts/commit/image-file.js.coffee deleted file mode 100644 index 9e5f49b1f699a337ff0f911532aafb8dc10f3239..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/commit/image-file.js.coffee +++ /dev/null @@ -1,126 +0,0 @@ -class @ImageFile - - # Width where images must fits in, for 2-up this gets divided by 2 - @availWidth = 900 - @viewModes = ['two-up', 'swipe'] - - constructor: (@file) -> - # Determine if old and new file has same dimensions, if not show 'two-up' view - this.requestImageInfo $('.two-up.view .frame.deleted img', @file), (deletedWidth, deletedHeight) => - this.requestImageInfo $('.two-up.view .frame.added img', @file), (width, height) => - if width == deletedWidth && height == deletedHeight - this.initViewModes() - else - this.initView('two-up') - - initViewModes: -> - viewMode = ImageFile.viewModes[0] - - $('.view-modes', @file).removeClass 'hide' - $('.view-modes-menu', @file).on 'click', 'li', (event) => - unless $(event.currentTarget).hasClass('active') - this.activateViewMode(event.currentTarget.className) - - this.activateViewMode(viewMode) - - activateViewMode: (viewMode) -> - $('.view-modes-menu li', @file) - .removeClass('active') - .filter(".#{viewMode}").addClass 'active' - $(".view:visible:not(.#{viewMode})", @file).fadeOut 200, => - $(".view.#{viewMode}", @file).fadeIn(200) - this.initView viewMode - - initView: (viewMode) -> - this.views[viewMode].call(this) - - prepareFrames = (view) -> - maxWidth = 0 - maxHeight = 0 - $('.frame', view).each (index, frame) => - width = $(frame).width() - height = $(frame).height() - maxWidth = if width > maxWidth then width else maxWidth - maxHeight = if height > maxHeight then height else maxHeight - .css - width: maxWidth - height: maxHeight - - [maxWidth, maxHeight] - - views: - 'two-up': -> - $('.two-up.view .wrap', @file).each (index, wrap) => - $('img', wrap).each -> - currentWidth = $(this).width() - if currentWidth > ImageFile.availWidth / 2 - $(this).width ImageFile.availWidth / 2 - - this.requestImageInfo $('img', wrap), (width, height) -> - $('.image-info .meta-width', wrap).text "#{width}px" - $('.image-info .meta-height', wrap).text "#{height}px" - $('.image-info', wrap).removeClass('hide') - - 'swipe': -> - maxWidth = 0 - maxHeight = 0 - - $('.swipe.view', @file).each (index, view) => - - [maxWidth, maxHeight] = prepareFrames(view) - - $('.swipe-frame', view).css - width: maxWidth + 16 - height: maxHeight + 28 - - $('.swipe-wrap', view).css - width: maxWidth + 1 - height: maxHeight + 2 - - $('.swipe-bar', view).css - left: 0 - .draggable - axis: 'x' - containment: 'parent' - drag: (event) -> - $('.swipe-wrap', view).width (maxWidth + 1) - $(this).position().left - stop: (event) -> - $('.swipe-wrap', view).width (maxWidth + 1) - $(this).position().left - - 'onion-skin': -> - maxWidth = 0 - maxHeight = 0 - - dragTrackWidth = $('.drag-track', @file).width() - $('.dragger', @file).width() - - $('.onion-skin.view', @file).each (index, view) => - - [maxWidth, maxHeight] = prepareFrames(view) - - $('.onion-skin-frame', view).css - width: maxWidth + 16 - height: maxHeight + 28 - - $('.swipe-wrap', view).css - width: maxWidth + 1 - height: maxHeight + 2 - - $('.dragger', view).css - left: dragTrackWidth - .draggable - axis: 'x' - containment: 'parent' - drag: (event) -> - $('.frame.added', view).css('opacity', $(this).position().left / dragTrackWidth) - stop: (event) -> - $('.frame.added', view).css('opacity', $(this).position().left / dragTrackWidth) - - - - requestImageInfo: (img, callback) -> - domImg = img.get(0) - if domImg.complete - callback.call(this, domImg.naturalWidth, domImg.naturalHeight) - else - img.on 'load', => - callback.call(this, domImg.naturalWidth, domImg.naturalHeight) diff --git a/app/assets/javascripts/commits.js.coffee b/app/assets/javascripts/commits.js.coffee deleted file mode 100644 index c183e78e513ed62a5f98ac13cfc41a15db308c41..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/commits.js.coffee +++ /dev/null @@ -1,55 +0,0 @@ -class @CommitsList - @data = - ref: null - limit: 0 - offset: 0 - @disable = false - - @showProgress: -> - $('.loading').show() - - @hideProgress: -> - $('.loading').hide() - - @init: (ref, limit) -> - $("body").on "click", ".day-commits-table li.commit", (event) -> - if event.target.nodeName != "A" - location.href = $(this).attr("url") - e.stopPropagation() - return false - - @data.ref = ref - @data.limit = limit - @data.offset = limit - - this.initLoadMore() - this.showProgress() - - @getOld: -> - this.showProgress() - $.ajax - type: "GET" - url: location.href - data: @data - complete: this.hideProgress - success: (data) -> - CommitsList.append(data.count, data.html) - dataType: "json" - - @append: (count, html) -> - $("#commits-list").append(html) - if count > 0 - @data.offset += count - else - @disable = true - - @initLoadMore: -> - $(document).unbind('scroll') - $(document).endlessScroll - bottomPixels: 400 - fireDelay: 1000 - fireOnce: true - ceaseFire: => - @disable - callback: => - this.getOld() diff --git a/app/assets/javascripts/confirm_danger_modal.js.coffee b/app/assets/javascripts/confirm_danger_modal.js.coffee deleted file mode 100644 index bb99edbd09eb5e21fba32774401da7d739902a01..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/confirm_danger_modal.js.coffee +++ /dev/null @@ -1,18 +0,0 @@ -class @ConfirmDangerModal - constructor: (form, text) -> - @form = form - $('.js-confirm-text').text(text || '') - $('.js-confirm-danger-input').val('') - $('#modal-confirm-danger').modal('show') - project_path = $('.js-confirm-danger-match').text() - submit = $('.js-confirm-danger-submit') - submit.disable() - - $('.js-confirm-danger-input').on 'input', -> - if rstrip($(@).val()) is project_path - submit.enable() - else - submit.disable() - - $('.js-confirm-danger-submit').on 'click', => - @form.submit() diff --git a/app/assets/javascripts/dashboard.js.coffee b/app/assets/javascripts/dashboard.js.coffee deleted file mode 100644 index 00ee503ff165c56ecafb3e63bd070cb465c8954d..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/dashboard.js.coffee +++ /dev/null @@ -1,3 +0,0 @@ -class @Dashboard - constructor: -> - new ProjectsList() diff --git a/app/assets/javascripts/diff.js.coffee b/app/assets/javascripts/diff.js.coffee deleted file mode 100644 index 069f91c30e1027dc4ccca0cf5d10ad9dc9727db7..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/diff.js.coffee +++ /dev/null @@ -1,44 +0,0 @@ -class @Diff - UNFOLD_COUNT = 20 - constructor: -> - $(document).off('click', '.js-unfold') - $(document).on('click', '.js-unfold', (event) => - target = $(event.target) - unfoldBottom = target.hasClass('js-unfold-bottom') - unfold = true - - [old_line, line_number] = @lineNumbers(target.parent()) - offset = line_number - old_line - - if unfoldBottom - line_number += 1 - since = line_number - to = line_number + UNFOLD_COUNT - else - [prev_old_line, prev_new_line] = @lineNumbers(target.parent().prev()) - line_number -= 1 - to = line_number - if line_number - UNFOLD_COUNT > prev_new_line + 1 - since = line_number - UNFOLD_COUNT - else - since = prev_new_line + 1 - unfold = false - - link = target.parents('.diff-file').attr('data-blob-diff-path') - params = - since: since - to: to - bottom: unfoldBottom - offset: offset - unfold: unfold - - $.get(link, params, (response) => - target.parent().replaceWith(response) - ) - ) - - lineNumbers: (line) -> - return ([0, 0]) unless line.children().length - lines = line.children().slice(0, 2) - line_numbers = ($(l).attr('data-linenumber') for l in lines) - (parseInt(line_number) for line_number in line_numbers) diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee deleted file mode 100644 index 330ebac6f75af495e413d841f4cde66fd0b294ae..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/dispatcher.js.coffee +++ /dev/null @@ -1,154 +0,0 @@ -$ -> - new Dispatcher() - -class Dispatcher - constructor: () -> - @initSearch() - @initPageScripts() - - initPageScripts: -> - page = $('body').attr('data-page') - project_id = $('body').attr('data-project-id') - - unless page - return false - - path = page.split(':') - shortcut_handler = null - - switch page - when 'projects:issues:index' - Issues.init() - shortcut_handler = new ShortcutsNavigation() - when 'projects:issues:show' - new Issue() - shortcut_handler = new ShortcutsIssueable() - new ZenMode() - when 'projects:milestones:show' - new Milestone() - when 'projects:milestones:new', 'projects:milestones:edit' - new ZenMode() - when 'projects:compare:show' - new Diff() - when 'projects:issues:new','projects:issues:edit' - GitLab.GfmAutoComplete.setup() - shortcut_handler = new ShortcutsNavigation() - new ZenMode() - new DropzoneInput($('.issue-form')) - if page == 'projects:issues:new' - new IssuableForm($('.issue-form')) - when 'projects:merge_requests:new', 'projects:merge_requests:edit' - GitLab.GfmAutoComplete.setup() - new Diff() - shortcut_handler = new ShortcutsNavigation() - new ZenMode() - new DropzoneInput($('.merge-request-form')) - if page == 'projects:merge_requests:new' - new IssuableForm($('.merge-request-form')) - when 'projects:merge_requests:show' - new Diff() - shortcut_handler = new ShortcutsIssueable() - new ZenMode() - when "projects:merge_requests:diffs" - new Diff() - new ZenMode() - when 'projects:merge_requests:index' - shortcut_handler = new ShortcutsNavigation() - MergeRequests.init() - when 'dashboard:show' - new Dashboard() - new Activities() - when 'dashboard:projects:starred' - new Activities() - new ProjectsList() - when 'projects:commit:show' - new Commit() - new Diff() - new ZenMode() - shortcut_handler = new ShortcutsNavigation() - when 'projects:commits:show' - shortcut_handler = new ShortcutsNavigation() - when 'projects:show' - new Activities() - shortcut_handler = new ShortcutsNavigation() - when 'groups:show' - new Activities() - shortcut_handler = new ShortcutsNavigation() - new ProjectsList() - when 'groups:group_members:index' - new GroupMembers() - new UsersSelect() - when 'projects:project_members:index' - new ProjectMembers() - new UsersSelect() - when 'groups:new', 'groups:edit', 'admin:groups:edit' - new GroupAvatar() - when 'projects:tree:show' - new TreeView() - shortcut_handler = new ShortcutsNavigation() - when 'projects:blob:show' - new BlobView() - shortcut_handler = new ShortcutsNavigation() - when 'projects:labels:new', 'projects:labels:edit' - new Labels() - when 'projects:network:show' - # Ensure we don't create a particular shortcut handler here. This is - # already created, where the network graph is created. - shortcut_handler = true - when 'projects:forks:new' - new ProjectFork() - when 'users:show' - new User() - new Activities() - when 'admin:users:show' - new ProjectsList() - - switch path.first() - when 'admin' - new Admin() - switch path[1] - when 'groups' - new UsersSelect() - when 'projects' - new NamespaceSelect() - when 'dashboard' - shortcut_handler = new ShortcutsDashboardNavigation() - when 'profiles' - new Profile() - when 'projects' - new Project() - new ProjectAvatar() - switch path[1] - when 'compare' - shortcut_handler = new ShortcutsNavigation() - when 'edit' - shortcut_handler = new ShortcutsNavigation() - new ProjectNew() - when 'new' - new ProjectNew() - when 'show' - new ProjectShow() - when 'issues', 'merge_requests' - new UsersSelect() - when 'wikis' - new Wikis() - shortcut_handler = new ShortcutsNavigation() - new ZenMode() - new DropzoneInput($('.wiki-form')) - when 'snippets', 'labels', 'graphs' - shortcut_handler = new ShortcutsNavigation() - when 'project_members', 'deploy_keys', 'hooks', 'services', 'protected_branches' - shortcut_handler = new ShortcutsNavigation() - - - # If we haven't installed a custom shortcut handler, install the default one - if not shortcut_handler - new Shortcuts() - - initSearch: -> - opts = $('.search-autocomplete-opts') - path = opts.data('autocomplete-path') - project_id = opts.data('autocomplete-project-id') - project_ref = opts.data('autocomplete-project-ref') - - new SearchAutocomplete(path, project_id, project_ref) diff --git a/app/assets/javascripts/dropzone_input.js.coffee b/app/assets/javascripts/dropzone_input.js.coffee deleted file mode 100644 index fca2a290e2d6ce8e2b7263b4d06d6c1d54a0dcfa..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/dropzone_input.js.coffee +++ /dev/null @@ -1,243 +0,0 @@ -class @DropzoneInput - constructor: (form) -> - Dropzone.autoDiscover = false - alertClass = "alert alert-danger alert-dismissable div-dropzone-alert" - alertAttr = "class=\"close\" data-dismiss=\"alert\"" + "aria-hidden=\"true\"" - divHover = "
" - divSpinner = "
" - divAlert = "
" - iconPaperclip = "" - iconSpinner = "" - btnAlert = "" - project_uploads_path = window.project_uploads_path or null - max_file_size = gon.max_file_size or 10 - - form_textarea = $(form).find("textarea.markdown-area") - form_textarea.wrap "
" - form_textarea.bind 'paste', (event) => - handlePaste(event) - - form_dropzone = $(form).find('.div-dropzone') - form_dropzone.parent().addClass "div-dropzone-wrapper" - form_dropzone.append divHover - $(".div-dropzone-hover").append iconPaperclip - form_dropzone.append divSpinner - $(".div-dropzone-spinner").append iconSpinner - $(".div-dropzone-spinner").css - "opacity": 0 - "display": "none" - - # Preview button - $(document).off "click", ".js-md-preview-button" - $(document).on "click", ".js-md-preview-button", (e) -> - ### - Shows the Markdown preview. - - Lets the server render GFM into Html and displays it. - ### - e.preventDefault() - form = $(this).closest("form") - # toggle tabs - form.find(".js-md-write-button").parent().removeClass "active" - form.find(".js-md-preview-button").parent().addClass "active" - - # toggle content - form.find(".md-write-holder").hide() - form.find(".md-preview-holder").show() - - preview = form.find(".js-md-preview") - mdText = form.find(".markdown-area").val() - if mdText.trim().length is 0 - preview.text "Nothing to preview." - else - preview.text "Loading..." - $.post($(this).data("url"), - md_text: mdText - ).success (previewData) -> - preview.html previewData - - # Write button - $(document).off "click", ".js-md-write-button" - $(document).on "click", ".js-md-write-button", (e) -> - ### - Shows the Markdown textarea. - ### - e.preventDefault() - form = $(this).closest("form") - # toggle tabs - form.find(".js-md-write-button").parent().addClass "active" - form.find(".js-md-preview-button").parent().removeClass "active" - - # toggle content - form.find(".md-write-holder").show() - form.find(".md-preview-holder").hide() - - dropzone = form_dropzone.dropzone( - url: project_uploads_path - dictDefaultMessage: "" - clickable: true - paramName: "file" - maxFilesize: max_file_size - uploadMultiple: false - headers: - "X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content") - - previewContainer: false - - processing: -> - $(".div-dropzone-alert").alert "close" - - dragover: -> - form_textarea.addClass "div-dropzone-focus" - form.find(".div-dropzone-hover").css "opacity", 0.7 - return - - dragleave: -> - form_textarea.removeClass "div-dropzone-focus" - form.find(".div-dropzone-hover").css "opacity", 0 - return - - drop: -> - form_textarea.removeClass "div-dropzone-focus" - form.find(".div-dropzone-hover").css "opacity", 0 - form_textarea.focus() - return - - success: (header, response) -> - child = $(dropzone[0]).children("textarea") - $(child).val $(child).val() + formatLink(response.link) + "\n" - return - - error: (temp, errorMessage) -> - errorAlert = $(form).find('.error-alert') - checkIfMsgExists = errorAlert.children().length - if checkIfMsgExists is 0 - errorAlert.append divAlert - $(".div-dropzone-alert").append btnAlert + errorMessage - return - - sending: -> - form_dropzone.find(".div-dropzone-spinner").css - "opacity": 0.7 - "display": "inherit" - return - - complete: -> - $(".dz-preview").remove() - $(".markdown-area").trigger "input" - $(".div-dropzone-spinner").css - "opacity": 0 - "display": "none" - return - ) - - child = $(dropzone[0]).children("textarea") - - formatLink = (link) -> - text = "[#{link.alt}](#{link.url})" - text = "!#{text}" if link.is_image - text - - handlePaste = (event) -> - pasteEvent = event.originalEvent - if pasteEvent.clipboardData and pasteEvent.clipboardData.items - image = isImage(pasteEvent) - if image - event.preventDefault() - - filename = getFilename(pasteEvent) or "image.png" - text = "{{" + filename + "}}" - pasteText(text) - uploadFile image.getAsFile(), filename - - isImage = (data) -> - i = 0 - while i < data.clipboardData.items.length - item = data.clipboardData.items[i] - if item.type.indexOf("image") isnt -1 - return item - i++ - return false - - pasteText = (text) -> - caretStart = $(child)[0].selectionStart - caretEnd = $(child)[0].selectionEnd - textEnd = $(child).val().length - - beforeSelection = $(child).val().substring 0, caretStart - afterSelection = $(child).val().substring caretEnd, textEnd - $(child).val beforeSelection + text + afterSelection - form_textarea.trigger "input" - - getFilename = (e) -> - if window.clipboardData and window.clipboardData.getData - value = window.clipboardData.getData("Text") - else if e.clipboardData and e.clipboardData.getData - value = e.clipboardData.getData("text/plain") - - value = value.split("\r") - value.first() - - uploadFile = (item, filename) -> - formData = new FormData() - formData.append "file", item, filename - $.ajax - url: project_uploads_path - type: "POST" - data: formData - dataType: "json" - processData: false - contentType: false - headers: - "X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content") - - beforeSend: -> - showSpinner() - closeAlertMessage() - - success: (e, textStatus, response) -> - insertToTextArea(filename, formatLink(response.responseJSON.link)) - - error: (response) -> - showError(response.responseJSON.message) - - complete: -> - closeSpinner() - - insertToTextArea = (filename, url) -> - $(child).val (index, val) -> - val.replace("{{" + filename + "}}", url + "\n") - - appendToTextArea = (url) -> - $(child).val (index, val) -> - val + url + "\n" - - showSpinner = (e) -> - form.find(".div-dropzone-spinner").css - "opacity": 0.7 - "display": "inherit" - - closeSpinner = -> - form.find(".div-dropzone-spinner").css - "opacity": 0 - "display": "none" - - showError = (message) -> - errorAlert = $(form).find('.error-alert') - checkIfMsgExists = errorAlert.children().length - if checkIfMsgExists is 0 - errorAlert.append divAlert - $(".div-dropzone-alert").append btnAlert + message - - closeAlertMessage = -> - form.find(".div-dropzone-alert").alert "close" - - form.find(".markdown-selector").click (e) -> - e.preventDefault() - $(@).closest('.gfm-form').find('.div-dropzone').click() - return - - formatLink: (link) -> - text = "[#{link.alt}](#{link.url})" - text = "!#{text}" if link.is_image - text diff --git a/app/assets/javascripts/extensions/array.js b/app/assets/javascripts/extensions/array.js deleted file mode 100644 index 24f9e00097cb51e7aa20d9ac0b374f7393038492..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/extensions/array.js +++ /dev/null @@ -1,7 +0,0 @@ -Array.prototype.first = function() { - return this[0]; -} - -Array.prototype.last = function() { - return this[this.length-1]; -} diff --git a/app/assets/javascripts/extensions/jquery.js.coffee b/app/assets/javascripts/extensions/jquery.js.coffee deleted file mode 100644 index 40fb6cb9fc343fd3d1092fe77fbb43c5e58b4d8d..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/extensions/jquery.js.coffee +++ /dev/null @@ -1,13 +0,0 @@ -$.fn.showAndHide = -> - $(@).show(). - delay(3000). - fadeOut() - -$.fn.enableButton = -> - $(@).removeAttr('disabled'). - removeClass('disabled') - -$.fn.disableButton = -> - $(@).attr('disabled', 'disabled'). - addClass('disabled') - diff --git a/app/assets/javascripts/flash.js.coffee b/app/assets/javascripts/flash.js.coffee deleted file mode 100644 index b39ab0c447580cbd7f5ef80f38f395da8f1bba1b..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/flash.js.coffee +++ /dev/null @@ -1,12 +0,0 @@ -class @Flash - constructor: (message, type)-> - flash = $(".flash-container") - flash.html("") - - $('
', - class: "flash-#{type}", - text: message - ).appendTo(".flash-container") - - flash.click -> $(@).fadeOut() - flash.show() diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee deleted file mode 100644 index 00d56ae5b4b0de2d24c87d34e4b072c9a3ab56c8..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ /dev/null @@ -1,67 +0,0 @@ -# Creates the variables for setting up GFM auto-completion - -window.GitLab ?= {} -GitLab.GfmAutoComplete = - # private_token: '' - dataSource: '' - # Emoji - Emoji: - template: '
  • ${name} ${name}
  • ' - - # Team Members - Members: - template: '
  • ${username} ${name}
  • ' - - # Issues and MergeRequests - Issues: - template: '
  • ${id} ${title}
  • ' - - # Add GFM auto-completion to all input fields, that accept GFM input. - setup: -> - input = $('.js-gfm-input') - - # Emoji - input.atwho - at: ':' - tpl: @Emoji.template - callbacks: - before_save: (emojis) => - $.map emojis, (em) => name: em.name, insert: em.name+ ':', image: em.path - - # Team Members - input.atwho - at: '@' - tpl: @Members.template - search_key: 'search' - callbacks: - before_save: (members) => - $.map members, (m) => name: m.name, username: m.username, search: "#{m.username} #{m.name}" - - input.atwho - at: '#' - alias: 'issues' - search_key: 'search' - tpl: @Issues.template - callbacks: - before_save: (issues) -> - $.map issues, (i) -> id: i.iid, title: sanitize(i.title), search: "#{i.iid} #{i.title}" - - input.atwho - at: '!' - alias: 'mergerequests' - search_key: 'search' - tpl: @Issues.template - callbacks: - before_save: (merges) -> - $.map merges, (m) -> id: m.iid, title: sanitize(m.title), search: "#{m.iid} #{m.title}" - - input.one "focus", => - $.getJSON(@dataSource).done (data) -> - # load members - input.atwho 'load', "@", data.members - # load issues - input.atwho 'load', "issues", data.issues - # load merge requests - input.atwho 'load', "mergerequests", data.mergerequests - # load emojis - input.atwho 'load', ":", data.emojis diff --git a/app/assets/javascripts/group_avatar.js.coffee b/app/assets/javascripts/group_avatar.js.coffee deleted file mode 100644 index 0825fd3ce52531a6873bf299e32428a16280e43a..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/group_avatar.js.coffee +++ /dev/null @@ -1,9 +0,0 @@ -class @GroupAvatar - constructor: -> - $('.js-choose-group-avatar-button').bind "click", -> - form = $(this).closest("form") - form.find(".js-group-avatar-input").click() - $('.js-group-avatar-input').bind "change", -> - form = $(this).closest("form") - filename = $(this).val().replace(/^.*[\\\/]/, '') - form.find(".js-avatar-filename").text(filename) diff --git a/app/assets/javascripts/groups.js.coffee b/app/assets/javascripts/groups.js.coffee deleted file mode 100644 index cc905e91ea2570de625c61fd243177bbc7d3b1b5..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/groups.js.coffee +++ /dev/null @@ -1,4 +0,0 @@ -class @GroupMembers - constructor: -> - $('li.group_member').bind 'ajax:success', -> - $(this).fadeOut() diff --git a/app/assets/javascripts/groups_select.js.coffee b/app/assets/javascripts/groups_select.js.coffee deleted file mode 100644 index 1084e2a17d191db263d3a039f5746b85dfaf909e..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/groups_select.js.coffee +++ /dev/null @@ -1,41 +0,0 @@ -class @GroupsSelect - constructor: -> - $('.ajax-groups-select').each (i, select) => - skip_ldap = $(select).hasClass('skip_ldap') - - $(select).select2 - placeholder: "Search for a group" - multiple: $(select).hasClass('multiselect') - minimumInputLength: 0 - query: (query) -> - Api.groups query.term, skip_ldap, (groups) -> - data = { results: groups } - query.callback(data) - - initSelection: (element, callback) -> - id = $(element).val() - if id isnt "" - Api.group(id, callback) - - - formatResult: (args...) => - @formatResult(args...) - formatSelection: (args...) => - @formatSelection(args...) - dropdownCssClass: "ajax-groups-dropdown" - escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results - m - - formatResult: (group) -> - if group.avatar_url - avatar = group.avatar_url - else - avatar = gon.default_avatar_url - - "
    -
    #{group.name}
    -
    #{group.path}
    -
    " - - formatSelection: (group) -> - group.name diff --git a/app/assets/javascripts/importer_status.js.coffee b/app/assets/javascripts/importer_status.js.coffee deleted file mode 100644 index be8d225e73b94ecd0b9a40c7a263461aae60055e..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/importer_status.js.coffee +++ /dev/null @@ -1,35 +0,0 @@ -class @ImporterStatus - constructor: (@jobs_url, @import_url) -> - this.initStatusPage() - this.setAutoUpdate() - - initStatusPage: -> - $(".js-add-to-import").click (event) => - new_namespace = null - tr = $(event.currentTarget).closest("tr") - id = tr.attr("id").replace("repo_", "") - if tr.find(".import-target input").length > 0 - new_namespace = tr.find(".import-target input").prop("value") - tr.find(".import-target").empty().append(new_namespace + "/" + tr.find(".import-target").data("project_name")) - $.post @import_url, {repo_id: id, new_namespace: new_namespace}, dataType: 'script' - - $(".js-import-all").click (event) => - $(".js-add-to-import").each -> - $(this).click() - - setAutoUpdate: -> - setInterval (=> - $.get @jobs_url, (data) => - $.each data, (i, job) => - job_item = $("#project_" + job.id) - status_field = job_item.find(".job-status") - - if job.import_status == 'finished' - job_item.removeClass("active").addClass("success") - status_field.html(' done') - else if job.import_status == 'started' - status_field.html(" started") - else - status_field.html(job.import_status) - - ), 4000 diff --git a/app/assets/javascripts/issuable_form.js.coffee b/app/assets/javascripts/issuable_form.js.coffee deleted file mode 100644 index abd58bcf9783bd3b801dfe5f214a4d34553a7ccc..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/issuable_form.js.coffee +++ /dev/null @@ -1,28 +0,0 @@ -class @IssuableForm - constructor: (@form) -> - @titleField = @form.find("input[name*='[title]']") - @descriptionField = @form.find("textarea[name*='[description]']") - - return unless @titleField.length && @descriptionField.length - - @initAutosave() - - @form.on "submit", @resetAutosave - @form.on "click", ".btn-cancel", @resetAutosave - - initAutosave: -> - new Autosave @titleField, [ - document.location.pathname, - document.location.search, - "title" - ] - - new Autosave @descriptionField, [ - document.location.pathname, - document.location.search, - "description" - ] - - resetAutosave: => - @titleField.data("autosave").reset() - @descriptionField.data("autosave").reset() diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee deleted file mode 100644 index 4e2e6550eb2260f059601cd5f1551099dd81b272..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/issue.js.coffee +++ /dev/null @@ -1,24 +0,0 @@ -class @Issue - constructor: -> - $('.edit-issue.inline-update input[type="submit"]').hide() - $(".context .inline-update").on "change", "select", -> - $(this).submit() - $(".context .inline-update").on "change", "#issue_assignee_id", -> - $(this).submit() - - if $("a.btn-close").length - $("li.task-list-item input:checkbox").prop("disabled", false) - - $('.task-list-item input:checkbox').off('change') - $('.task-list-item input:checkbox').change('issue', updateTaskState) - - $('.issue-details').waitForImages -> - $('.issuable-affix').affix offset: - top: -> - @top = ($('.issuable-affix').offset().top - 70) - bottom: -> - @bottom = $('.footer').outerHeight(true) - $('.issuable-affix').on 'affix.bs.affix', -> - $(@).width($(@).outerWidth()) - .on 'affixed-top.bs.affix affixed-bottom.bs.affix', -> - $(@).width('') diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee deleted file mode 100644 index 40bb9e9cb0cc45f1d79d96959b0635ba91379986..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/issues.js.coffee +++ /dev/null @@ -1,85 +0,0 @@ -@Issues = - init: -> - Issues.initSearch() - Issues.initSelects() - Issues.initChecks() - - $("body").on "ajax:success", ".close_issue, .reopen_issue", -> - t = $(this) - totalIssues = undefined - reopen = t.hasClass("reopen_issue") - $(".issue_counter").each -> - issue = $(this) - totalIssues = parseInt($(this).html(), 10) - if reopen and issue.closest(".main_menu").length - $(this).html totalIssues + 1 - else - $(this).html totalIssues - 1 - $("body").on "click", ".issues-other-filters .dropdown-menu a", -> - $('.issues-list').block( - message: null, - overlayCSS: - backgroundColor: '#DDD' - opacity: .4 - ) - - reload: -> - Issues.initSelects() - Issues.initChecks() - $('#filter_issue_search').val($('#issue_search').val()) - - initSelects: -> - $("select#update_status").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#update_assignee_id").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#update_milestone_id").select2(width: 'resolve', dropdownAutoWidth: true) - $("select#label_name").select2(width: 'resolve', dropdownAutoWidth: true) - $("#milestone_id, #assignee_id, #label_name").on "change", -> - $(this).closest("form").submit() - - initChecks: -> - $(".check_all_issues").click -> - $(".selected_issue").prop("checked", @checked) - Issues.checkChanged() - - $(".selected_issue").bind "change", Issues.checkChanged - - # Make sure we trigger ajax request only after user stop typing - initSearch: -> - @timer = null - $("#issue_search").keyup -> - clearTimeout(@timer) - @timer = setTimeout(Issues.filterResults, 500) - - filterResults: => - form = $("#issue_search_form") - search = $("#issue_search").val() - $('.issues-holder').css("opacity", '0.5') - issues_url = form.attr('action') + '? '+ form.serialize() - - $.ajax - type: "GET" - url: form.attr('action') - data: form.serialize() - complete: -> - $('.issues-holder').css("opacity", '1.0') - success: (data) -> - $('.issues-holder').html(data.html) - # Change url so if user reload a page - search results are saved - History.replaceState {page: issues_url}, document.title, issues_url - Issues.reload() - dataType: "json" - - checkChanged: -> - checked_issues = $(".selected_issue:checked") - if checked_issues.length > 0 - ids = [] - $.each checked_issues, (index, value) -> - ids.push $(value).attr("data-id") - - $("#update_issues_ids").val ids - $(".issues-other-filters").hide() - $(".issues_bulk_update").show() - else - $("#update_issues_ids").val [] - $(".issues_bulk_update").hide() - $(".issues-other-filters").show() diff --git a/app/assets/javascripts/labels.js.coffee b/app/assets/javascripts/labels.js.coffee deleted file mode 100644 index 1bc8840f9ac887233a9e5cf9ec8e394a5c6fdbf7..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/labels.js.coffee +++ /dev/null @@ -1,33 +0,0 @@ -class @Labels - constructor: -> - form = $('.label-form') - @setupLabelForm(form) - @cleanBinding() - @addBinding() - @updateColorPreview() - - addBinding: -> - $(document).on 'click', '.suggest-colors a', @setSuggestedColor - $(document).on 'input', 'input#label_color', @updateColorPreview - - cleanBinding: -> - $(document).off 'click', '.suggest-colors a' - $(document).off 'input', 'input#label_color' - - # Initializes the form to disable the save button if no color or title is entered - setupLabelForm: (form) -> - disableButtonIfAnyEmptyField form, '.form-control', form.find('.js-save-button') - - # Updates the the preview color with the hex-color input - updateColorPreview: => - previewColor = $('input#label_color').val() - $('div.label-color-preview').css('background-color', previewColor) - - # Updates the preview color with a click on a suggested color - setSuggestedColor: (e) => - color = $(e.currentTarget).data('color') - $('input#label_color').val(color) - @updateColorPreview() - # Notify the form, that color has changed - $('.label-form').trigger('keyup') - e.preventDefault() diff --git a/app/assets/javascripts/lib/jquery.timeago.js b/app/assets/javascripts/lib/jquery.timeago.js deleted file mode 100644 index cc17aa7d3d1883a93d53b2f192415cf9042e2461..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/lib/jquery.timeago.js +++ /dev/null @@ -1,181 +0,0 @@ -/** - * Timeago is a jQuery plugin that makes it easy to support automatically - * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago"). - * - * @name timeago - * @version 1.1.0 - * @requires jQuery v1.2.3+ - * @author Ryan McGeary - * @license MIT License - http://www.opensource.org/licenses/mit-license.php - * - * For usage and examples, visit: - * http://timeago.yarp.com/ - * - * Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org) - */ - -(function (factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - $.timeago = function(timestamp) { - if (timestamp instanceof Date) { - return inWords(timestamp); - } else if (typeof timestamp === "string") { - return inWords($.timeago.parse(timestamp)); - } else if (typeof timestamp === "number") { - return inWords(new Date(timestamp)); - } else { - return inWords($.timeago.datetime(timestamp)); - } - }; - var $t = $.timeago; - - $.extend($.timeago, { - settings: { - refreshMillis: 60000, - allowFuture: false, - strings: { - prefixAgo: null, - prefixFromNow: null, - suffixAgo: "ago", - suffixFromNow: "from now", - seconds: "less than a minute", - minute: "about a minute", - minutes: "%d minutes", - hour: "about an hour", - hours: "about %d hours", - day: "a day", - days: "%d days", - month: "about a month", - months: "%d months", - year: "about a year", - years: "%d years", - wordSeparator: " ", - numbers: [] - } - }, - inWords: function(distanceMillis) { - var $l = this.settings.strings; - var prefix = $l.prefixAgo; - var suffix = $l.suffixAgo; - if (this.settings.allowFuture) { - if (distanceMillis < 0) { - prefix = $l.prefixFromNow; - suffix = $l.suffixFromNow; - } - } - - var seconds = Math.abs(distanceMillis) / 1000; - var minutes = seconds / 60; - var hours = minutes / 60; - var days = hours / 24; - var years = days / 365; - - function substitute(stringOrFunction, number) { - var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; - var value = ($l.numbers && $l.numbers[number]) || number; - return string.replace(/%d/i, value); - } - - var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || - seconds < 90 && substitute($l.minute, 1) || - minutes < 45 && substitute($l.minutes, Math.round(minutes)) || - minutes < 90 && substitute($l.hour, 1) || - hours < 24 && substitute($l.hours, Math.round(hours)) || - hours < 42 && substitute($l.day, 1) || - days < 30 && substitute($l.days, Math.round(days)) || - days < 45 && substitute($l.month, 1) || - days < 365 && substitute($l.months, Math.round(days / 30)) || - years < 1.5 && substitute($l.year, 1) || - substitute($l.years, Math.round(years)); - - var separator = $l.wordSeparator || ""; - if ($l.wordSeparator === undefined) { separator = " "; } - return $.trim([prefix, words, suffix].join(separator)); - }, - parse: function(iso8601) { - var s = $.trim(iso8601); - s = s.replace(/\.\d+/,""); // remove milliseconds - s = s.replace(/-/,"/").replace(/-/,"/"); - s = s.replace(/T/," ").replace(/Z/," UTC"); - s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 - return new Date(s); - }, - datetime: function(elem) { - var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title"); - return $t.parse(iso8601); - }, - isTime: function(elem) { - // jQuery's `is()` doesn't play well with HTML5 in IE - return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time"); - } - }); - - // functions that can be called via $(el).timeago('action') - // init is default when no action is given - // functions are called with context of a single element - var functions = { - init: function(){ - var refresh_el = $.proxy(refresh, this); - refresh_el(); - var $s = $t.settings; - if ($s.refreshMillis > 0) { - setInterval(refresh_el, $s.refreshMillis); - } - }, - update: function(time){ - $(this).data('timeago', { datetime: $t.parse(time) }); - refresh.apply(this); - } - }; - - $.fn.timeago = function(action, options) { - var fn = action ? functions[action] : functions.init; - if(!fn){ - throw new Error("Unknown function name '"+ action +"' for timeago"); - } - // each over objects here and call the requested function - this.each(function(){ - fn.call(this, options); - }); - return this; - }; - - function refresh() { - var data = prepareData(this); - if (!isNaN(data.datetime)) { - $(this).text(inWords(data.datetime)); - } - return this; - } - - function prepareData(element) { - element = $(element); - if (!element.data("timeago")) { - element.data("timeago", { datetime: $t.datetime(element) }); - var text = $.trim(element.text()); - if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) { - element.attr("title", text); - } - } - return element.data("timeago"); - } - - function inWords(date) { - return $t.inWords(distance(date)); - } - - function distance(date) { - return (new Date().getTime() - date.getTime()); - } - - // fix for IE6 suckage - document.createElement("abbr"); - document.createElement("time"); -})); diff --git a/app/assets/javascripts/lib/md5.js b/app/assets/javascripts/lib/md5.js deleted file mode 100644 index b63716eaad2f8f90678b99ccac2eb7f226214847..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/lib/md5.js +++ /dev/null @@ -1,211 +0,0 @@ -function md5 (str) { - // http://kevin.vanzonneveld.net - // + original by: Webtoolkit.info (http://www.webtoolkit.info/) - // + namespaced by: Michael White (http://getsprink.com) - // + tweaked by: Jack - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + input by: Brett Zamir (http://brett-zamir.me) - // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // - depends on: utf8_encode - // * example 1: md5('Kevin van Zonneveld'); - // * returns 1: '6e658d4bfcb59cc13f96c14450ac40b9' - var xl; - - var rotateLeft = function (lValue, iShiftBits) { - return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)); - }; - - var addUnsigned = function (lX, lY) { - var lX4, lY4, lX8, lY8, lResult; - lX8 = (lX & 0x80000000); - lY8 = (lY & 0x80000000); - lX4 = (lX & 0x40000000); - lY4 = (lY & 0x40000000); - lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); - if (lX4 & lY4) { - return (lResult ^ 0x80000000 ^ lX8 ^ lY8); - } - if (lX4 | lY4) { - if (lResult & 0x40000000) { - return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); - } else { - return (lResult ^ 0x40000000 ^ lX8 ^ lY8); - } - } else { - return (lResult ^ lX8 ^ lY8); - } - }; - - var _F = function (x, y, z) { - return (x & y) | ((~x) & z); - }; - var _G = function (x, y, z) { - return (x & z) | (y & (~z)); - }; - var _H = function (x, y, z) { - return (x ^ y ^ z); - }; - var _I = function (x, y, z) { - return (y ^ (x | (~z))); - }; - - var _FF = function (a, b, c, d, x, s, ac) { - a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac)); - return addUnsigned(rotateLeft(a, s), b); - }; - - var _GG = function (a, b, c, d, x, s, ac) { - a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac)); - return addUnsigned(rotateLeft(a, s), b); - }; - - var _HH = function (a, b, c, d, x, s, ac) { - a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac)); - return addUnsigned(rotateLeft(a, s), b); - }; - - var _II = function (a, b, c, d, x, s, ac) { - a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac)); - return addUnsigned(rotateLeft(a, s), b); - }; - - var convertToWordArray = function (str) { - var lWordCount; - var lMessageLength = str.length; - var lNumberOfWords_temp1 = lMessageLength + 8; - var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64; - var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16; - var lWordArray = new Array(lNumberOfWords - 1); - var lBytePosition = 0; - var lByteCount = 0; - while (lByteCount < lMessageLength) { - lWordCount = (lByteCount - (lByteCount % 4)) / 4; - lBytePosition = (lByteCount % 4) * 8; - lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition)); - lByteCount++; - } - lWordCount = (lByteCount - (lByteCount % 4)) / 4; - lBytePosition = (lByteCount % 4) * 8; - lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition); - lWordArray[lNumberOfWords - 2] = lMessageLength << 3; - lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29; - return lWordArray; - }; - - var wordToHex = function (lValue) { - var wordToHexValue = "", - wordToHexValue_temp = "", - lByte, lCount; - for (lCount = 0; lCount <= 3; lCount++) { - lByte = (lValue >>> (lCount * 8)) & 255; - wordToHexValue_temp = "0" + lByte.toString(16); - wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2); - } - return wordToHexValue; - }; - - var x = [], - k, AA, BB, CC, DD, a, b, c, d, S11 = 7, - S12 = 12, - S13 = 17, - S14 = 22, - S21 = 5, - S22 = 9, - S23 = 14, - S24 = 20, - S31 = 4, - S32 = 11, - S33 = 16, - S34 = 23, - S41 = 6, - S42 = 10, - S43 = 15, - S44 = 21; - - str = this.utf8_encode(str); - x = convertToWordArray(str); - a = 0x67452301; - b = 0xEFCDAB89; - c = 0x98BADCFE; - d = 0x10325476; - - xl = x.length; - for (k = 0; k < xl; k += 16) { - AA = a; - BB = b; - CC = c; - DD = d; - a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478); - d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756); - c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB); - b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE); - a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF); - d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A); - c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613); - b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501); - a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8); - d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF); - c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1); - b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE); - a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122); - d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193); - c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E); - b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821); - a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562); - d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340); - c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51); - b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA); - a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D); - d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453); - c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681); - b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8); - a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6); - d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6); - c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87); - b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED); - a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905); - d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8); - c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9); - b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A); - a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942); - d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681); - c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122); - b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C); - a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44); - d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9); - c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60); - b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70); - a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6); - d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA); - c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085); - b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05); - a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039); - d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5); - c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8); - b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665); - a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244); - d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97); - c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7); - b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039); - a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3); - d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92); - c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D); - b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1); - a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F); - d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0); - c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314); - b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1); - a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82); - d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235); - c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB); - b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391); - a = addUnsigned(a, AA); - b = addUnsigned(b, BB); - c = addUnsigned(c, CC); - d = addUnsigned(d, DD); - } - - var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d); - - return temp.toLowerCase(); -} diff --git a/app/assets/javascripts/lib/utf8_encode.js b/app/assets/javascripts/lib/utf8_encode.js deleted file mode 100644 index 39ffe44dae0ef78c6e22dbe5f0d60bb3265c94af..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/lib/utf8_encode.js +++ /dev/null @@ -1,70 +0,0 @@ -function utf8_encode (argString) { - // http://kevin.vanzonneveld.net - // + original by: Webtoolkit.info (http://www.webtoolkit.info/) - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + improved by: sowberry - // + tweaked by: Jack - // + bugfixed by: Onno Marsman - // + improved by: Yves Sucaet - // + bugfixed by: Onno Marsman - // + bugfixed by: Ulrich - // + bugfixed by: Rafal Kukawski - // + improved by: kirilloid - // + bugfixed by: kirilloid - // * example 1: utf8_encode('Kevin van Zonneveld'); - // * returns 1: 'Kevin van Zonneveld' - - if (argString === null || typeof argString === "undefined") { - return ""; - } - - var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n"); - var utftext = '', - start, end, stringl = 0; - - start = end = 0; - stringl = string.length; - for (var n = 0; n < stringl; n++) { - var c1 = string.charCodeAt(n); - var enc = null; - - if (c1 < 128) { - end++; - } else if (c1 > 127 && c1 < 2048) { - enc = String.fromCharCode( - (c1 >> 6) | 192, - ( c1 & 63) | 128 - ); - } else if (c1 & 0xF800 != 0xD800) { - enc = String.fromCharCode( - (c1 >> 12) | 224, - ((c1 >> 6) & 63) | 128, - ( c1 & 63) | 128 - ); - } else { // surrogate pairs - if (c1 & 0xFC00 != 0xD800) { throw new RangeError("Unmatched trail surrogate at " + n); } - var c2 = string.charCodeAt(++n); - if (c2 & 0xFC00 != 0xDC00) { throw new RangeError("Unmatched lead surrogate at " + (n-1)); } - c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000; - enc = String.fromCharCode( - (c1 >> 18) | 240, - ((c1 >> 12) & 63) | 128, - ((c1 >> 6) & 63) | 128, - ( c1 & 63) | 128 - ); - } - if (enc !== null) { - if (end > start) { - utftext += string.slice(start, end); - } - utftext += enc; - start = end = n + 1; - } - } - - if (end > start) { - utftext += string.slice(start, stringl); - } - - return utftext; -} diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee deleted file mode 100644 index fc75f1438368c198c2610768af32c0965d4a905f..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/merge_request.js.coffee +++ /dev/null @@ -1,166 +0,0 @@ -class @MergeRequest - constructor: (@opts) -> - @initContextWidget() - this.$el = $('.merge-request') - @diffs_loaded = if @opts.action == 'diffs' then true else false - @commits_loaded = false - - this.activateTab(@opts.action) - - this.bindEvents() - - this.initMergeWidget() - this.$('.show-all-commits').on 'click', => - this.showAllCommits() - - modal = $('#modal_merge_info').modal(show: false) - - disableButtonIfEmptyField '#commit_message', '.accept_merge_request' - - if $("a.btn-close").length - $("li.task-list-item input:checkbox").prop("disabled", false) - - $('.merge-request-details').waitForImages -> - $('.issuable-affix').affix offset: - top: -> - @top = ($('.issuable-affix').offset().top - 70) - bottom: -> - @bottom = $('.footer').outerHeight(true) - $('.issuable-affix').on 'affix.bs.affix', -> - $(@).width($(@).outerWidth()) - .on 'affixed-top.bs.affix affixed-bottom.bs.affix', -> - $(@).width('') - - # Local jQuery finder - $: (selector) -> - this.$el.find(selector) - - initContextWidget: -> - $('.edit-merge_request.inline-update input[type="submit"]').hide() - $(".context .inline-update").on "change", "select", -> - $(this).submit() - $(".context .inline-update").on "change", "#merge_request_assignee_id", -> - $(this).submit() - - initMergeWidget: -> - this.showState( @opts.current_status ) - - if this.$('.automerge_widget').length and @opts.check_enable - $.get @opts.url_to_automerge_check, (data) => - this.showState( data.merge_status ) - , 'json' - - if @opts.ci_enable - $.get @opts.url_to_ci_check, (data) => - this.showCiState data.status - if data.coverage - this.showCiCoverage data.coverage - , 'json' - - bindEvents: -> - this.$('.merge-request-tabs').on 'click', 'a', (event) => - a = $(event.currentTarget) - - href = a.attr('href') - History.replaceState {path: href}, document.title, href - - event.preventDefault() - - this.$('.merge-request-tabs').on 'click', 'li', (event) => - this.activateTab($(event.currentTarget).data('action')) - - this.$('.accept_merge_request').on 'click', -> - $('.automerge_widget.can_be_merged').hide() - $('.merge-in-progress').show() - - this.$('.remove_source_branch').on 'click', -> - $('.remove_source_branch_widget').hide() - $('.remove_source_branch_in_progress').show() - - this.$(".remove_source_branch").on "ajax:success", (e, data, status, xhr) -> - location.reload() - - this.$(".remove_source_branch").on "ajax:error", (e, data, status, xhr) => - this.$('.remove_source_branch_widget').hide() - this.$('.remove_source_branch_in_progress').hide() - this.$('.remove_source_branch_widget.failed').show() - - $('.task-list-item input:checkbox').off('change') - $('.task-list-item input:checkbox').change('merge_request', updateTaskState) - - activateTab: (action) -> - this.$('.merge-request-tabs li').removeClass 'active' - this.$('.tab-content').hide() - switch action - when 'diffs' - this.$('.merge-request-tabs .diffs-tab').addClass 'active' - this.loadDiff() unless @diffs_loaded - this.$('.diffs').show() - $(".diff-header").trigger("sticky_kit:recalc") - when 'commits' - this.$('.merge-request-tabs .commits-tab').addClass 'active' - this.$('.commits').show() - else - this.$('.merge-request-tabs .notes-tab').addClass 'active' - this.$('.notes').show() - - showState: (state) -> - $('.automerge_widget').hide() - $('.automerge_widget.' + state).show() - - showCiState: (state) -> - $('.ci_widget').hide() - allowed_states = ["failed", "canceled", "running", "pending", "success"] - if state in allowed_states - $('.ci_widget.ci-' + state).show() - switch state - when "failed", "canceled" - @setMergeButtonClass('btn-danger') - when "running", "pending" - @setMergeButtonClass('btn-warning') - else - $('.ci_widget.ci-error').show() - @setMergeButtonClass('btn-danger') - - showCiCoverage: (coverage) -> - cov_html = $('') - cov_html.addClass('ci-coverage') - cov_html.text('Coverage ' + coverage + '%') - $('.ci_widget:visible').append(cov_html) - - loadDiff: (event) -> - $.ajax - type: 'GET' - url: this.$('.merge-request-tabs .diffs-tab a').attr('href') + ".json" - beforeSend: => - this.$('.mr-loading-status .loading').show() - complete: => - @diffs_loaded = true - this.$('.mr-loading-status .loading').hide() - success: (data) => - this.$(".diffs").html(data.html) - dataType: 'json' - - showAllCommits: -> - this.$('.first-commits').remove() - this.$('.all-commits').removeClass 'hide' - - alreadyOrCannotBeMerged: -> - this.$('.automerge_widget').hide() - this.$('.merge-in-progress').hide() - this.$('.automerge_widget.already_cannot_be_merged').show() - - setMergeButtonClass: (css_class) -> - $('.accept_merge_request').removeClass("btn-create").addClass(css_class) - - mergeInProgress: -> - $.ajax - type: 'GET' - url: $('.merge-request').data('url') - success: (data) => - switch data.state - when 'merged' - location.reload() - else - setTimeout(merge_request.mergeInProgress, 3000) - dataType: 'json' diff --git a/app/assets/javascripts/merge_requests.js.coffee b/app/assets/javascripts/merge_requests.js.coffee deleted file mode 100644 index 83434c1b9ba0e7b7702c63ae01f95506c400159a..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/merge_requests.js.coffee +++ /dev/null @@ -1,35 +0,0 @@ -# -# * Filter merge requests -# -@MergeRequests = - init: -> - MergeRequests.initSearch() - - # Make sure we trigger ajax request only after user stop typing - initSearch: -> - @timer = null - $("#issue_search").keyup -> - clearTimeout(@timer) - @timer = setTimeout(MergeRequests.filterResults, 500) - - filterResults: => - form = $("#issue_search_form") - search = $("#issue_search").val() - $('.merge-requests-holder').css("opacity", '0.5') - issues_url = form.attr('action') + '? '+ form.serialize() - - $.ajax - type: "GET" - url: form.attr('action') - data: form.serialize() - complete: -> - $('.merge-requests-holder').css("opacity", '1.0') - success: (data) -> - $('.merge-requests-holder').html(data.html) - # Change url so if user reload a page - search results are saved - History.replaceState {page: issues_url}, document.title, issues_url - MergeRequests.reload() - dataType: "json" - - reload: -> - $('#filter_issue_search').val($('#issue_search').val()) diff --git a/app/assets/javascripts/milestone.js.coffee b/app/assets/javascripts/milestone.js.coffee deleted file mode 100644 index d644d50b66927a5bbb4a000630f6dec3dc9dc30e..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/milestone.js.coffee +++ /dev/null @@ -1,124 +0,0 @@ -class @Milestone - @updateIssue: (li, issue_url, data) -> - $.ajax - type: "PUT" - url: issue_url - data: data - success: (data) -> - if data.saved == true - if data.assignee_avatar_url - img_tag = $('') - img_tag.attr('src', data.assignee_avatar_url) - img_tag.addClass('avatar s16') - $(li).find('.assignee-icon').html(img_tag) - else - $(li).find('.assignee-icon').html('') - $(li).effect 'highlight' - else - new Flash("Issue update failed", 'alert') - dataType: "json" - - @sortIssues: (data) -> - sort_issues_url = location.href + "/sort_issues" - - $.ajax - type: "PUT" - url: sort_issues_url - data: data - success: (data) -> - if data.saved != true - new Flash("Issues update failed", 'alert') - dataType: "json" - - @sortMergeRequests: (data) -> - sort_mr_url = location.href + "/sort_merge_requests" - - $.ajax - type: "PUT" - url: sort_mr_url - data: data - success: (data) -> - if data.saved != true - new Flash("MR update failed", 'alert') - dataType: "json" - - @updateMergeRequest: (li, merge_request_url, data) -> - $.ajax - type: "PUT" - url: merge_request_url - data: data - success: (data) -> - if data.saved == true - if data.assignee_avatar_url - img_tag = $('') - img_tag.attr('src', data.assignee_avatar_url) - img_tag.addClass('avatar s16') - $(li).find('.assignee-icon').html(img_tag) - else - $(li).find('.assignee-icon').html('') - $(li).effect 'highlight' - else - new Flash("Issue update failed", 'alert') - dataType: "json" - - constructor: -> - @bindIssuesSorting() - @bindMergeRequestSorting() - - bindIssuesSorting: -> - $("#issues-list-unassigned, #issues-list-ongoing, #issues-list-closed").sortable( - connectWith: ".issues-sortable-list", - dropOnEmpty: true, - items: "li:not(.ui-sort-disabled)", - update: (event, ui) -> - data = $(this).sortable("serialize") - Milestone.sortIssues(data) - - receive: (event, ui) -> - new_state = $(this).data('state') - issue_id = ui.item.data('iid') - issue_url = ui.item.data('url') - - data = switch new_state - when 'ongoing' - "issue[assignee_id]=" + gon.current_user_id - when 'unassigned' - "issue[assignee_id]=" - when 'closed' - "issue[state_event]=close" - - if $(ui.sender).data('state') == "closed" - data += "&issue[state_event]=reopen" - - Milestone.updateIssue(ui.item, issue_url, data) - - ).disableSelection() - - bindMergeRequestSorting: -> - $("#merge_requests-list-unassigned, #merge_requests-list-ongoing, #merge_requests-list-closed").sortable( - connectWith: ".merge_requests-sortable-list", - dropOnEmpty: true, - items: "li:not(.ui-sort-disabled)", - update: (event, ui) -> - data = $(this).sortable("serialize") - Milestone.sortMergeRequests(data) - - receive: (event, ui) -> - new_state = $(this).data('state') - merge_request_id = ui.item.data('iid') - merge_request_url = ui.item.data('url') - - data = switch new_state - when 'ongoing' - "merge_request[assignee_id]=" + gon.current_user_id - when 'unassigned' - "merge_request[assignee_id]=" - when 'closed' - "merge_request[state_event]=close" - - if $(ui.sender).data('state') == "closed" - data += "&merge_request[state_event]=reopen" - - Milestone.updateMergeRequest(ui.item, merge_request_url, data) - - ).disableSelection() diff --git a/app/assets/javascripts/namespace_select.js.coffee b/app/assets/javascripts/namespace_select.js.coffee deleted file mode 100644 index a02c4515ccc1ea1b386f2fee5ad8ebf86f9fce24..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/namespace_select.js.coffee +++ /dev/null @@ -1,25 +0,0 @@ -class @NamespaceSelect - constructor: -> - namespaceFormatResult = (namespace) -> - markup = "
    " - markup += "" + namespace.kind + "" - markup += "" + namespace.path + "" - markup += "
    " - markup - - formatSelection = (namespace) -> - namespace.kind + ": " + namespace.path - - $('.ajax-namespace-select').each (i, select) -> - $(select).select2 - placeholder: "Search for namespace" - multiple: $(select).hasClass('multiselect') - minimumInputLength: 0 - query: (query) -> - Api.namespaces query.term, (namespaces) -> - data = { results: namespaces } - query.callback(data) - - dropdownCssClass: "ajax-namespace-dropdown" - formatResult: namespaceFormatResult - formatSelection: formatSelection diff --git a/app/assets/javascripts/network.js.coffee b/app/assets/javascripts/network.js.coffee deleted file mode 100644 index f4ef07a50a7e10efbab544384eec31020d5f6922..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/network.js.coffee +++ /dev/null @@ -1,9 +0,0 @@ -class @Network - constructor: (opts) -> - $("#filter_ref").click -> - $(this).closest('form').submit() - - @branch_graph = new BranchGraph($(".network-graph"), opts) - - vph = $(window).height() - 250 - $('.network-graph').css 'height': (vph + 'px') diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee deleted file mode 100644 index 6dfe10f000604a115a7799df3777089588276c95..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/notes.js.coffee +++ /dev/null @@ -1,481 +0,0 @@ -class @Notes - @interval: null - - constructor: (notes_url, note_ids, last_fetched_at) -> - @notes_url = notes_url - @notes_url = gon.relative_url_root + @notes_url if gon.relative_url_root? - @note_ids = note_ids - @last_fetched_at = last_fetched_at - @noteable_url = document.URL - @initRefresh() - @setupMainTargetNoteForm() - @cleanBinding() - @addBinding() - - addBinding: -> - # add note to UI after creation - $(document).on "ajax:success", ".js-main-target-form", @addNote - $(document).on "ajax:success", ".js-discussion-note-form", @addDiscussionNote - - # change note in UI after update - $(document).on "ajax:success", "form.edit_note", @updateNote - - # Edit note link - $(document).on "click", ".js-note-edit", @showEditForm - $(document).on "click", ".note-edit-cancel", @cancelEdit - - # Reopen and close actions for Issue/MR combined with note form submit - $(document).on "click", ".js-note-target-reopen", @targetReopen - $(document).on "click", ".js-note-target-close", @targetClose - $(document).on "click", ".js-comment-button", @updateCloseButton - $(document).on "keyup", ".js-note-text", @updateTargetButtons - - # remove a note (in general) - $(document).on "click", ".js-note-delete", @removeNote - - # delete note attachment - $(document).on "click", ".js-note-attachment-delete", @removeAttachment - - # reset main target form after submit - $(document).on "ajax:complete", ".js-main-target-form", @reenableTargetFormSubmitButton - $(document).on "ajax:success", ".js-main-target-form", @resetMainTargetForm - - # update the file name when an attachment is selected - $(document).on "change", ".js-note-attachment-input", @updateFormAttachment - - # reply to diff/discussion notes - $(document).on "click", ".js-discussion-reply-button", @replyToDiscussionNote - - # add diff note - $(document).on "click", ".js-add-diff-note-button", @addDiffNote - - # hide diff note form - $(document).on "click", ".js-close-discussion-note-form", @cancelDiscussionForm - - # fetch notes when tab becomes visible - $(document).on "visibilitychange", @visibilityChange - - @notes_forms = '.js-main-target-form textarea, .js-discussion-note-form textarea' - # Chrome doesn't fire keypress or keyup for Command+Enter, so we need keydown. - $(document).on('keydown', @notes_forms, (e) -> - return if e.originalEvent.repeat - if e.keyCode == 10 || ((e.metaKey || e.ctrlKey) && e.keyCode == 13) - $(@).parents('form').submit() - ) - - cleanBinding: -> - $(document).off "ajax:success", ".js-main-target-form" - $(document).off "ajax:success", ".js-discussion-note-form" - $(document).off "ajax:success", "form.edit_note" - $(document).off "click", ".js-note-edit" - $(document).off "click", ".note-edit-cancel" - $(document).off "click", ".js-note-delete" - $(document).off "click", ".js-note-attachment-delete" - $(document).off "ajax:complete", ".js-main-target-form" - $(document).off "ajax:success", ".js-main-target-form" - $(document).off "click", ".js-discussion-reply-button" - $(document).off "click", ".js-add-diff-note-button" - $(document).off "visibilitychange" - $(document).off "keydown", @notes_forms - $(document).off "keyup", ".js-note-text" - $(document).off "click", ".js-note-target-reopen" - $(document).off "click", ".js-note-target-close" - - initRefresh: -> - clearInterval(Notes.interval) - Notes.interval = setInterval => - @refresh() - , 15000 - - refresh: -> - unless document.hidden or (@noteable_url != document.URL) - @getContent() - - getContent: -> - $.ajax - url: @notes_url - data: "last_fetched_at=" + @last_fetched_at - dataType: "json" - success: (data) => - notes = data.notes - @last_fetched_at = data.last_fetched_at - $.each notes, (i, note) => - @renderNote(note) - - - ### - Render note in main comments area. - - Note: for rendering inline notes use renderDiscussionNote - ### - renderNote: (note) -> - # render note if it not present in loaded list - # or skip if rendered - if @isNewNote(note) - @note_ids.push(note.id) - $('ul.main-notes-list').append(note.html) - - ### - Check if note does not exists on page - ### - isNewNote: (note) -> - $.inArray(note.id, @note_ids) == -1 - - - ### - Render note in discussion area. - - Note: for rendering inline notes use renderDiscussionNote - ### - renderDiscussionNote: (note) -> - @note_ids.push(note.id) - form = $("form[rel='" + note.discussion_id + "']") - row = form.closest("tr") - - # is this the first note of discussion? - if row.is(".js-temp-notes-holder") - # insert the note and the reply button after the temp row - row.after note.discussion_html - - # remove the note (will be added again below) - row.next().find(".note").remove() - - # Add note to 'Changes' page discussions - $(".notes[rel='" + note.discussion_id + "']").append note.html - - # Init discussion on 'Discussion' page if it is merge request page - if $('body').attr('data-page').indexOf('projects:merge_request') == 0 - $('ul.main-notes-list').append(note.discussion_with_diff_html) - else - # append new note to all matching discussions - $(".notes[rel='" + note.discussion_id + "']").append note.html - - # cleanup after successfully creating a diff/discussion note - @removeDiscussionNoteForm(form) - - ### - Called in response the main target form has been successfully submitted. - - Removes any errors. - Resets text and preview. - Resets buttons. - ### - resetMainTargetForm: -> - form = $(".js-main-target-form") - - # remove validation errors - form.find(".js-errors").remove() - - # reset text and preview - form.find(".js-md-write-button").click() - form.find(".js-note-text").val("").trigger "input" - - form.find(".js-note-text").data("autosave").reset() - - reenableTargetFormSubmitButton: -> - form = $(".js-main-target-form") - - form.find(".js-note-text").trigger "input" - - ### - Shows the main form and does some setup on it. - - Sets some hidden fields in the form. - ### - setupMainTargetNoteForm: -> - - # find the form - form = $(".js-new-note-form") - - # insert the form after the button - form.clone().replaceAll $(".js-main-target-form") - form = form.prev("form") - - # show the form - @setupNoteForm(form) - - # fix classes - form.removeClass "js-new-note-form" - form.addClass "js-main-target-form" - - # remove unnecessary fields and buttons - form.find("#note_line_code").remove() - form.find(".js-close-discussion-note-form").remove() - - ### - General note form setup. - - deactivates the submit button when text is empty - hides the preview button when text is empty - setup GFM auto complete - show the form - ### - setupNoteForm: (form) -> - disableButtonIfEmptyField form.find(".js-note-text"), form.find(".js-comment-button") - form.removeClass "js-new-note-form" - form.find('.div-dropzone').remove() - - # setup preview buttons - form.find(".js-md-write-button, .js-md-preview-button").tooltip placement: "left" - previewButton = form.find(".js-md-preview-button") - - textarea = form.find(".js-note-text") - - textarea.on "input", -> - if $(this).val().trim() isnt "" - previewButton.removeClass("turn-off").addClass "turn-on" - else - previewButton.removeClass("turn-on").addClass "turn-off" - - new Autosave textarea, [ - "Note" - form.find("#note_commit_id").val() - form.find("#note_line_code").val() - form.find("#note_noteable_type").val() - form.find("#note_noteable_id").val() - ] - - # remove notify commit author checkbox for non-commit notes - form.find(".js-notify-commit-author").remove() if form.find("#note_noteable_type").val() isnt "Commit" - GitLab.GfmAutoComplete.setup() - new DropzoneInput(form) - form.show() - - ### - Called in response to the new note form being submitted - - Adds new note to list. - ### - addNote: (xhr, note, status) => - @renderNote(note) - @updateVotes() - - ### - Called in response to the new note form being submitted - - Adds new note to list. - ### - addDiscussionNote: (xhr, note, status) => - @renderDiscussionNote(note) - - ### - Called in response to the edit note form being submitted - - Updates the current note field. - ### - updateNote: (xhr, note, status) => - note_li = $(".note-row-" + note.id) - note_li.replaceWith(note.html) - note_li.find('.note-edit-form').hide() - note_li.find('.note-body > .note-text').show() - - ### - Called in response to clicking the edit note link - - Replaces the note text with the note edit form - Adds a hidden div with the original content of the note to fill the edit note form with - if the user cancels - ### - showEditForm: (e) -> - e.preventDefault() - note = $(this).closest(".note") - note.find(".note-body > .note-text").hide() - note.find(".note-header").hide() - base_form = note.find(".note-edit-form") - form = base_form.clone().insertAfter(base_form) - form.addClass('current-note-edit-form') - form.find('.div-dropzone').remove() - - # Show the attachment delete link - note.find(".js-note-attachment-delete").show() - - # Setup markdown form - GitLab.GfmAutoComplete.setup() - new DropzoneInput(form) - - form.show() - textarea = form.find("textarea") - textarea.focus() - disableButtonIfEmptyField textarea, form.find(".js-comment-button") - - ### - Called in response to clicking the edit note link - - Hides edit form - ### - cancelEdit: (e) -> - e.preventDefault() - note = $(this).closest(".note") - note.find(".note-body > .note-text").show() - note.find(".note-header").show() - note.find(".current-note-edit-form").remove() - - ### - Called in response to deleting a note of any kind. - - Removes the actual note from view. - Removes the whole discussion if the last note is being removed. - ### - removeNote: -> - note = $(this).closest(".note") - notes = note.closest(".notes") - - # check if this is the last note for this line - if notes.find(".note").length is 1 - - # for discussions - notes.closest(".discussion").remove() - - # for diff lines - notes.closest("tr").remove() - - note.remove() - - ### - Called in response to clicking the delete attachment link - - Removes the attachment wrapper view, including image tag if it exists - Resets the note editing form - ### - removeAttachment: -> - note = $(this).closest(".note") - note.find(".note-attachment").remove() - note.find(".note-body > .note-text").show() - note.find(".js-note-attachment-delete").hide() - note.find(".note-edit-form").hide() - - ### - Called when clicking on the "reply" button for a diff line. - - Shows the note form below the notes. - ### - replyToDiscussionNote: (e) => - form = $(".js-new-note-form") - replyLink = $(e.target).closest(".js-discussion-reply-button") - replyLink.hide() - - # insert the form after the button - form.clone().insertAfter replyLink - - # show the form - @setupDiscussionNoteForm(replyLink, replyLink.next("form")) - - ### - Shows the diff or discussion form and does some setup on it. - - Sets some hidden fields in the form. - - Note: dataHolder must have the "discussionId", "lineCode", "noteableType" - and "noteableId" data attributes set. - ### - setupDiscussionNoteForm: (dataHolder, form) => - # setup note target - form.attr "rel", dataHolder.data("discussionId") - form.find("#note_commit_id").val dataHolder.data("commitId") - form.find("#note_line_code").val dataHolder.data("lineCode") - form.find("#note_noteable_type").val dataHolder.data("noteableType") - form.find("#note_noteable_id").val dataHolder.data("noteableId") - @setupNoteForm form - form.find(".js-note-text").focus() - form.addClass "js-discussion-note-form" - - ### - Called when clicking on the "add a comment" button on the side of a diff line. - - Inserts a temporary row for the form below the line. - Sets up the form and shows it. - ### - addDiffNote: (e) => - e.preventDefault() - link = e.currentTarget - form = $(".js-new-note-form") - row = $(link).closest("tr") - nextRow = row.next() - - # does it already have notes? - if nextRow.is(".notes_holder") - replyButton = nextRow.find(".js-discussion-reply-button") - if replyButton.length > 0 - $.proxy(@replyToDiscussionNote, replyButton).call() - else - # add a notes row and insert the form - row.after "" - form.clone().appendTo row.next().find(".notes_content") - - # show the form - @setupDiscussionNoteForm $(link), row.next().find("form") - - ### - Called in response to "cancel" on a diff note form. - - Shows the reply button again. - Removes the form and if necessary it's temporary row. - ### - removeDiscussionNoteForm: (form)-> - row = form.closest("tr") - - form.find(".js-note-text").data("autosave").reset() - - # show the reply button (will only work for replies) - form.prev(".js-discussion-reply-button").show() - if row.is(".js-temp-notes-holder") - # remove temporary row for diff lines - row.remove() - else - # only remove the form - form.remove() - - - cancelDiscussionForm: (e) => - e.preventDefault() - form = $(".js-new-note-form") - form = $(e.target).closest(".js-discussion-note-form") - @removeDiscussionNoteForm(form) - - updateVotes: -> - true - - ### - Called after an attachment file has been selected. - - Updates the file name for the selected attachment. - ### - updateFormAttachment: -> - form = $(this).closest("form") - - # get only the basename - filename = $(this).val().replace(/^.*[\\\/]/, "") - form.find(".js-attachment-filename").text filename - - ### - Called when the tab visibility changes - ### - visibilityChange: => - @refresh() - - targetReopen: (e) => - @submitNoteForm($(e.target).parents('form')) - - targetClose: (e) => - @submitNoteForm($(e.target).parents('form')) - - submitNoteForm: (form) => - noteText = form.find(".js-note-text").val() - if noteText.trim().length > 0 - form.submit() - - updateCloseButton: (e) => - textarea = $(e.target) - form = textarea.parents('form') - form.find('.js-note-target-close').text('Close') - - updateTargetButtons: (e) => - textarea = $(e.target) - form = textarea.parents('form') - - if textarea.val().trim().length > 0 - form.find('.js-note-target-reopen').text('Comment & reopen') - form.find('.js-note-target-close').text('Comment & close') - else - form.find('.js-note-target-reopen').text('Reopen') - form.find('.js-note-target-close').text('Close') diff --git a/app/assets/javascripts/pager.js.coffee b/app/assets/javascripts/pager.js.coffee deleted file mode 100644 index fe83dc0410ef940f26637025f5e5439d4aa4874d..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/pager.js.coffee +++ /dev/null @@ -1,42 +0,0 @@ -@Pager = - init: (@limit = 0, preload, @disable = false) -> - @loading = $(".loading") - if preload - @offset = 0 - @getOld() - else - @offset = @limit - @initLoadMore() - - getOld: -> - @loading.show() - $.ajax - type: "GET" - url: location.href - data: "limit=" + @limit + "&offset=" + @offset - complete: => - @loading.hide() - success: (data) -> - Pager.append(data.count, data.html) - dataType: "json" - - append: (count, html) -> - $(".content_list").append html - if count > 0 - @offset += count - else - @disable = true - - initLoadMore: -> - $(document).unbind('scroll') - $(document).endlessScroll - bottomPixels: 400 - fireDelay: 1000 - fireOnce: true - ceaseFire: -> - Pager.disable - - callback: (i) => - unless @loading.is(':visible') - @loading.show() - Pager.getOld() diff --git a/app/assets/javascripts/profile.js.coffee b/app/assets/javascripts/profile.js.coffee deleted file mode 100644 index de356fbec77f9c0f243fa1fabebdd99afeb4c07a..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/profile.js.coffee +++ /dev/null @@ -1,29 +0,0 @@ -class @Profile - constructor: -> - $('.edit_user .application-theme input, .edit_user .code-preview-theme input').click -> - # Submit the form - $('.edit_user').submit() - - new Flash("Appearance settings saved", "notice") - - $('.update-username form').on 'ajax:before', -> - $('.loading-gif').show() - $(this).find('.update-success').hide() - $(this).find('.update-failed').hide() - - $('.update-username form').on 'ajax:complete', -> - $(this).find('.btn-save').enableButton() - $(this).find('.loading-gif').hide() - - $('.update-notifications').on 'ajax:complete', -> - $(this).find('.btn-save').enableButton() - - - $('.js-choose-user-avatar-button').bind "click", -> - form = $(this).closest("form") - form.find(".js-user-avatar-input").click() - - $('.js-user-avatar-input').bind "change", -> - form = $(this).closest("form") - filename = $(this).val().replace(/^.*[\\\/]/, '') - form.find(".js-avatar-filename").text(filename) diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee deleted file mode 100644 index eb8c1fa1426446ebb862f2a7b0165603e0f9edd8..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/project.js.coffee +++ /dev/null @@ -1,26 +0,0 @@ -class @Project - constructor: -> - # Git clone panel switcher - scope = $ '.git-clone-holder' - if scope.length > 0 - $('a, button', scope).click -> - $('a, button', scope).removeClass 'active' - $(@).addClass 'active' - $('#project_clone', scope).val $(@).data 'clone' - $(".clone").text("").append $(@).data 'clone' - - # Ref switcher - $('.project-refs-select').on 'change', -> - $(@).parents('form').submit() - - $('.hide-no-ssh-message').on 'click', (e) -> - path = '/' - $.cookie('hide_no_ssh_message', 'false', { path: path }) - $(@).parents('.no-ssh-key-message').remove() - e.preventDefault() - - $('.hide-no-password-message').on 'click', (e) -> - path = '/' - $.cookie('hide_no_password_message', 'false', { path: path }) - $(@).parents('.no-password-message').remove() - e.preventDefault() diff --git a/app/assets/javascripts/project_avatar.js.coffee b/app/assets/javascripts/project_avatar.js.coffee deleted file mode 100644 index 8bec6e2ccca0046469046bd4b3f338cfec827a74..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/project_avatar.js.coffee +++ /dev/null @@ -1,9 +0,0 @@ -class @ProjectAvatar - constructor: -> - $('.js-choose-project-avatar-button').bind 'click', -> - form = $(this).closest('form') - form.find('.js-project-avatar-input').click() - $('.js-project-avatar-input').bind 'change', -> - form = $(this).closest('form') - filename = $(this).val().replace(/^.*[\\\/]/, '') - form.find('.js-avatar-filename').text(filename) diff --git a/app/assets/javascripts/project_fork.js.coffee b/app/assets/javascripts/project_fork.js.coffee deleted file mode 100644 index e15a1c4ef76781725d3dac9c99471861dcfbe774..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/project_fork.js.coffee +++ /dev/null @@ -1,5 +0,0 @@ -class @ProjectFork - constructor: -> - $('.fork-thumbnail a').on 'click', -> - $('.fork-namespaces').hide() - $('.save-project-loader').show() diff --git a/app/assets/javascripts/project_import.js.coffee b/app/assets/javascripts/project_import.js.coffee deleted file mode 100644 index 6633564a0792c6c877737cd72d0bd4d0daa2d268..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/project_import.js.coffee +++ /dev/null @@ -1,5 +0,0 @@ -class @ProjectImport - constructor: -> - setTimeout -> - Turbolinks.visit(location.href) - , 5000 diff --git a/app/assets/javascripts/project_members.js.coffee b/app/assets/javascripts/project_members.js.coffee deleted file mode 100644 index 896ba7e53eefeec6e78b1effb252255c7378c8cb..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/project_members.js.coffee +++ /dev/null @@ -1,4 +0,0 @@ -class @ProjectMembers - constructor: -> - $('li.project_member').bind 'ajax:success', -> - $(this).fadeOut() diff --git a/app/assets/javascripts/project_new.js.coffee b/app/assets/javascripts/project_new.js.coffee deleted file mode 100644 index 836269c44f93b22e3db6ac3b9a8a6756fbad2daa..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/project_new.js.coffee +++ /dev/null @@ -1,11 +0,0 @@ -class @ProjectNew - constructor: -> - $('.project-edit-container').on 'ajax:before', => - $('.project-edit-container').hide() - $('.save-project-loader').show() - - @initEvents() - - - initEvents: -> - disableButtonIfEmptyField '#project_name', '.project-submit' diff --git a/app/assets/javascripts/project_show.js.coffee b/app/assets/javascripts/project_show.js.coffee deleted file mode 100644 index 6828ae471e51426e0c538712dd6b6b68bd1f4904..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/project_show.js.coffee +++ /dev/null @@ -1,15 +0,0 @@ -class @ProjectShow - constructor: -> - $('.project-home-panel .star').on 'ajax:success', (e, data, status, xhr) -> - $(@).toggleClass('on').find('.count').html(data.star_count) - .on 'ajax:error', (e, xhr, status, error) -> - new Flash('Star toggle failed. Try again later.', 'alert') - - $("a[data-toggle='tab']").on "shown.bs.tab", (e) -> - $.cookie "default_view", $(e.target).attr("href"), { expires: 30, path: '/' } - - defaultView = $.cookie("default_view") - if defaultView - $("a[href=" + defaultView + "]").tab "show" - else - $("a[data-toggle='tab']:first").tab "show" diff --git a/app/assets/javascripts/projects_list.js.coffee b/app/assets/javascripts/projects_list.js.coffee deleted file mode 100644 index c0e36d1ccc5ce47b9c8ee4b2944d36829c9373ee..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/projects_list.js.coffee +++ /dev/null @@ -1,24 +0,0 @@ -class @ProjectsList - constructor: -> - $(".projects-list .js-expand").on 'click', (e) -> - e.preventDefault() - list = $(this).closest('.projects-list') - list.find("li").show() - list.find("li.bottom").hide() - - $(".projects-list-filter").keyup -> - terms = $(this).val() - uiBox = $(this).closest('.panel') - if terms == "" || terms == undefined - uiBox.find(".projects-list li").show() - else - uiBox.find(".projects-list li").each (index) -> - name = $(this).find(".filter-title").text() - - if name.toLowerCase().search(terms.toLowerCase()) == -1 - $(this).hide() - else - $(this).show() - uiBox.find(".projects-list li.bottom").hide() - - diff --git a/app/assets/javascripts/protected_branches.js.coffee b/app/assets/javascripts/protected_branches.js.coffee deleted file mode 100644 index 5753c9d4e72140aca1c96772ffab88d36501dec4..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/protected_branches.js.coffee +++ /dev/null @@ -1,21 +0,0 @@ -$ -> - $(".protected-branches-list :checkbox").change (e) -> - name = $(this).attr("name") - if name == "developers_can_push" - id = $(this).val() - checked = $(this).is(":checked") - url = $(this).data("url") - $.ajax - type: "PUT" - url: url - dataType: "json" - data: - id: id - developers_can_push: checked - - success: -> - row = $(e.target) - row.closest('tr').effect('highlight') - - error: -> - new Flash("Failed to update branch!", "alert") diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee deleted file mode 100644 index c1801365266f1f63f7f353f93848e8472cd013b1..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/search_autocomplete.js.coffee +++ /dev/null @@ -1,11 +0,0 @@ -class @SearchAutocomplete - constructor: (search_autocomplete_path, project_id, project_ref) -> - project_id = '' unless project_id - project_ref = '' unless project_ref - query = "?project_id=" + project_id + "&project_ref=" + project_ref - - $("#search").autocomplete - source: search_autocomplete_path + query - minLength: 1 - select: (event, ui) -> - location.href = ui.item.url diff --git a/app/assets/javascripts/shortcuts.js.coffee b/app/assets/javascripts/shortcuts.js.coffee deleted file mode 100644 index e9aeb1e9525ccd00e733b625178e5b2fcb8fa84a..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/shortcuts.js.coffee +++ /dev/null @@ -1,30 +0,0 @@ -class @Shortcuts - constructor: -> - @enabledHelp = [] - Mousetrap.reset() - Mousetrap.bind('?', @selectiveHelp) - Mousetrap.bind('s', Shortcuts.focusSearch) - - selectiveHelp: (e) => - Shortcuts.showHelp(e, @enabledHelp) - - @showHelp: (e, location) -> - if $('#modal-shortcuts').length > 0 - $('#modal-shortcuts').modal('show') - else - $.ajax( - url: '/help/shortcuts', - dataType: 'script', - success: (e) -> - if location and location.length > 0 - for l in location - $(l).show() - else - $('.hidden-shortcut').show() - $('.js-more-help-button').remove() - ) - e.preventDefault() - - @focusSearch: (e) -> - $('#search').focus() - e.preventDefault() diff --git a/app/assets/javascripts/shortcuts_dashboard_navigation.js.coffee b/app/assets/javascripts/shortcuts_dashboard_navigation.js.coffee deleted file mode 100644 index 4a05bdccdb36888d52dbabcc94b323180259da90..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/shortcuts_dashboard_navigation.js.coffee +++ /dev/null @@ -1,14 +0,0 @@ -#= require shortcuts - -class @ShortcutsDashboardNavigation extends Shortcuts - constructor: -> - super() - Mousetrap.bind('g a', -> ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-activity')) - Mousetrap.bind('g i', -> ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-issues')) - Mousetrap.bind('g m', -> ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-merge_requests')) - Mousetrap.bind('g p', -> ShortcutsDashboardNavigation.findAndFollowLink('.shortcuts-projects')) - - @findAndFollowLink: (selector) -> - link = $(selector).attr('href') - if link - window.location = link diff --git a/app/assets/javascripts/shortcuts_issueable.coffee b/app/assets/javascripts/shortcuts_issueable.coffee deleted file mode 100644 index b8dae71e037310266cbea613e05361bc03e3d2d5..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/shortcuts_issueable.coffee +++ /dev/null @@ -1,19 +0,0 @@ -#= require shortcuts_navigation - -class @ShortcutsIssueable extends ShortcutsNavigation - constructor: (isMergeRequest) -> - super() - Mousetrap.bind('a', -> - $('.js-assignee').select2('open') - return false - ) - Mousetrap.bind('m', -> - $('.js-milestone').select2('open') - return false - ) - - if isMergeRequest - @enabledHelp.push('.hidden-shortcut.merge_reuests') - else - @enabledHelp.push('.hidden-shortcut.issues') - diff --git a/app/assets/javascripts/shortcuts_navigation.coffee b/app/assets/javascripts/shortcuts_navigation.coffee deleted file mode 100644 index 31895fbf2bc3a0a1b73d16cf762a881dc9570ce9..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/shortcuts_navigation.coffee +++ /dev/null @@ -1,20 +0,0 @@ -#= require shortcuts - -class @ShortcutsNavigation extends Shortcuts - constructor: -> - super() - Mousetrap.bind('g p', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-project')) - Mousetrap.bind('g f', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-tree')) - Mousetrap.bind('g c', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-commits')) - Mousetrap.bind('g n', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-network')) - Mousetrap.bind('g g', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-graphs')) - Mousetrap.bind('g i', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-issues')) - Mousetrap.bind('g m', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-merge_requests')) - Mousetrap.bind('g w', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-wiki')) - Mousetrap.bind('g s', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-snippets')) - @enabledHelp.push('.hidden-shortcut.project') - - @findAndFollowLink: (selector) -> - link = $(selector).attr('href') - if link - window.location = link diff --git a/app/assets/javascripts/shortcuts_network.js.coffee b/app/assets/javascripts/shortcuts_network.js.coffee deleted file mode 100644 index cc95ad7ebfed105d114e61f7f941083c3c1207ad..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/shortcuts_network.js.coffee +++ /dev/null @@ -1,12 +0,0 @@ -#= require shortcuts_navigation - -class @ShortcutsNetwork extends ShortcutsNavigation - constructor: (@graph) -> - super() - Mousetrap.bind(['left', 'h'], @graph.scrollLeft) - Mousetrap.bind(['right', 'l'], @graph.scrollRight) - Mousetrap.bind(['up', 'k'], @graph.scrollUp) - Mousetrap.bind(['down', 'j'], @graph.scrollDown) - Mousetrap.bind(['shift+up', 'shift+k'], @graph.scrollTop) - Mousetrap.bind(['shift+down', 'shift+j'], @graph.scrollBottom) - @enabledHelp.push('.hidden-shortcut.network') diff --git a/app/assets/javascripts/sidebar.js.coffee b/app/assets/javascripts/sidebar.js.coffee deleted file mode 100644 index 2e3f56082574a021af20bfee05d1f7b4225f40e6..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/sidebar.js.coffee +++ /dev/null @@ -1,9 +0,0 @@ -$(document).on("click", '.toggle-nav-collapse', (e) -> - e.preventDefault() - collapsed = 'page-sidebar-collapsed' - expanded = 'page-sidebar-expanded' - - $('.page-with-sidebar').toggleClass("#{collapsed} #{expanded}") - $('.toggle-nav-collapse i').toggleClass("fa-angle-right fa-angle-left") - $.cookie("collapsed_nav", $('.page-with-sidebar').hasClass(collapsed), { path: '/' }) -) diff --git a/app/assets/javascripts/stat_graph.js.coffee b/app/assets/javascripts/stat_graph.js.coffee deleted file mode 100644 index f36c71fd25e51f113c721019a9cc3badfdfcdfc2..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/stat_graph.js.coffee +++ /dev/null @@ -1,6 +0,0 @@ -class @StatGraph - @log: {} - @get_log: -> - @log - @set_log: (data) -> - @log = data diff --git a/app/assets/javascripts/stat_graph_contributors.js.coffee b/app/assets/javascripts/stat_graph_contributors.js.coffee deleted file mode 100644 index 27f0fd31d5025491e46ea9bcb3104c9dc4e12043..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/stat_graph_contributors.js.coffee +++ /dev/null @@ -1,69 +0,0 @@ -class @ContributorsStatGraph - init: (log) -> - @parsed_log = ContributorsStatGraphUtil.parse_log(log) - @set_current_field("commits") - total_commits = ContributorsStatGraphUtil.get_total_data(@parsed_log, @field) - author_commits = ContributorsStatGraphUtil.get_author_data(@parsed_log, @field) - @add_master_graph(total_commits) - @add_authors_graph(author_commits) - @change_date_header() - add_master_graph: (total_data) -> - @master_graph = new ContributorsMasterGraph(total_data) - @master_graph.draw() - add_authors_graph: (author_data) -> - @authors = [] - limited_author_data = author_data.slice(0, 100) - _.each(limited_author_data, (d) => - author_header = @create_author_header(d) - $(".contributors-list").append(author_header) - @authors[d.author_name] = author_graph = new ContributorsAuthorGraph(d.dates) - author_graph.draw() - ) - format_author_commit_info: (author) -> - commits = $('', { - class: 'graph-author-commits-count' - }) - commits.text(author.commits + " commits") - $('').append(commits) - - create_author_header: (author) -> - list_item = $('
  • ', { - class: 'person' - style: 'display: block;' - }) - author_name = $('

    ' + author.author_name + '

    ') - author_email = $('

    ' + author.author_email + '

    ') - author_commit_info_span = $('', { - class: 'commits' - }) - author_commit_info = @format_author_commit_info(author) - author_commit_info_span.html(author_commit_info) - list_item.append(author_name) - list_item.append(author_email) - list_item.append(author_commit_info_span) - list_item - redraw_master: -> - total_data = ContributorsStatGraphUtil.get_total_data(@parsed_log, @field) - @master_graph.set_data(total_data) - @master_graph.redraw() - redraw_authors: -> - $("ol").html("") - x_domain = ContributorsGraph.prototype.x_domain - author_commits = ContributorsStatGraphUtil.get_author_data(@parsed_log, @field, x_domain) - _.each(author_commits, (d) => - @redraw_author_commit_info(d) - $(@authors[d.author_name].list_item).appendTo("ol") - @authors[d.author_name].set_data(d.dates) - @authors[d.author_name].redraw() - ) - set_current_field: (field) -> - @field = field - change_date_header: -> - x_domain = ContributorsGraph.prototype.x_domain - print_date_format = d3.time.format("%B %e %Y") - print = print_date_format(x_domain[0]) + " - " + print_date_format(x_domain[1]) - $("#date_header").text(print) - redraw_author_commit_info: (author) -> - author_list_item = $(@authors[author.author_name].list_item) - author_commit_info = @format_author_commit_info(author) - author_list_item.find("span").html(author_commit_info) diff --git a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee b/app/assets/javascripts/stat_graph_contributors_graph.js.coffee deleted file mode 100644 index 8b82d20c6c25f2f9151d158ae448617bd778482b..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee +++ /dev/null @@ -1,167 +0,0 @@ -class @ContributorsGraph - MARGIN: - top: 20 - right: 20 - bottom: 30 - left: 50 - x_domain: null - y_domain: null - dates: [] - @set_x_domain: (data) => - @prototype.x_domain = data - @set_y_domain: (data) => - @prototype.y_domain = [0, d3.max(data, (d) -> - d.commits = d.commits ? d.additions ? d.deletions - )] - @init_x_domain: (data) => - @prototype.x_domain = d3.extent(data, (d) -> - d.date - ) - @init_y_domain: (data) => - @prototype.y_domain = [0, d3.max(data, (d) -> - d.commits = d.commits ? d.additions ? d.deletions - )] - @init_domain: (data) => - @init_x_domain(data) - @init_y_domain(data) - @set_dates: (data) => - @prototype.dates = data - set_x_domain: -> - @x.domain(@x_domain) - set_y_domain: -> - @y.domain(@y_domain) - set_domain: -> - @set_x_domain() - @set_y_domain() - create_scale: (width, height) -> - @x = d3.time.scale().range([0, width]).clamp(true) - @y = d3.scale.linear().range([height, 0]).nice() - draw_x_axis: -> - @svg.append("g").attr("class", "x axis").attr("transform", "translate(0, #{@height})") - .call(@x_axis) - draw_y_axis: -> - @svg.append("g").attr("class", "y axis").call(@y_axis) - set_data: (data) -> - @data = data - -class @ContributorsMasterGraph extends ContributorsGraph - constructor: (@data) -> - @width = $('.container').width() - 345 - @height = 200 - @x = null - @y = null - @x_axis = null - @y_axis = null - @area = null - @svg = null - @brush = null - @x_max_domain = null - process_dates: (data) -> - dates = @get_dates(data) - @parse_dates(data) - ContributorsGraph.set_dates(dates) - get_dates: (data) -> - _.pluck(data, 'date') - parse_dates: (data) -> - parseDate = d3.time.format("%Y-%m-%d").parse - data.forEach((d) -> - d.date = parseDate(d.date) - ) - create_scale: -> - super @width, @height - create_axes: -> - @x_axis = d3.svg.axis().scale(@x).orient("bottom") - @y_axis = d3.svg.axis().scale(@y).orient("left").ticks(5) - create_svg: -> - @svg = d3.select("#contributors-master").append("svg") - .attr("width", @width + @MARGIN.left + @MARGIN.right) - .attr("height", @height + @MARGIN.top + @MARGIN.bottom) - .attr("class", "tint-box") - .append("g") - .attr("transform", "translate(" + @MARGIN.left + "," + @MARGIN.top + ")") - create_area: (x, y) -> - @area = d3.svg.area().x((d) -> - x(d.date) - ).y0(@height).y1((d) -> - xa = d.commits = d.commits ? d.additions ? d.deletions - y(xa) - ).interpolate("basis") - create_brush: -> - @brush = d3.svg.brush().x(@x).on("brushend", @update_content) - draw_path: (data) -> - @svg.append("path").datum(data).attr("class", "area").attr("d", @area) - add_brush: -> - @svg.append("g").attr("class", "selection").call(@brush).selectAll("rect").attr("height", @height) - update_content: => - ContributorsGraph.set_x_domain(if @brush.empty() then @x_max_domain else @brush.extent()) - $("#brush_change").trigger('change') - draw: -> - @process_dates(@data) - @create_scale() - @create_axes() - ContributorsGraph.init_domain(@data) - @x_max_domain = @x_domain - @set_domain() - @create_area(@x, @y) - @create_svg() - @create_brush() - @draw_path(@data) - @draw_x_axis() - @draw_y_axis() - @add_brush() - redraw: -> - @process_dates(@data) - ContributorsGraph.set_y_domain(@data) - @set_y_domain() - @svg.select("path").datum(@data) - @svg.select("path").attr("d", @area) - @svg.select(".y.axis").call(@y_axis) - -class @ContributorsAuthorGraph extends ContributorsGraph - constructor: (@data) -> - @width = $('.container').width()/2 - 225 - @height = 200 - @x = null - @y = null - @x_axis = null - @y_axis = null - @area = null - @svg = null - @list_item = null - create_scale: -> - super @width, @height - create_axes: -> - @x_axis = d3.svg.axis().scale(@x).orient("bottom").ticks(8) - @y_axis = d3.svg.axis().scale(@y).orient("left").ticks(5) - create_area: (x, y) -> - @area = d3.svg.area().x((d) -> - parseDate = d3.time.format("%Y-%m-%d").parse - x(parseDate(d)) - ).y0(@height).y1((d) => - if @data[d]? then y(@data[d]) else y(0) - ).interpolate("basis") - create_svg: -> - @list_item = d3.selectAll(".person")[0].pop() - @svg = d3.select(@list_item).append("svg") - .attr("width", @width + @MARGIN.left + @MARGIN.right) - .attr("height", @height + @MARGIN.top + @MARGIN.bottom) - .attr("class", "spark") - .append("g") - .attr("transform", "translate(" + @MARGIN.left + "," + @MARGIN.top + ")") - draw_path: (data) -> - @svg.append("path").datum(data).attr("class", "area-contributor").attr("d", @area) - draw: -> - @create_scale() - @create_axes() - @set_domain() - @create_area(@x, @y) - @create_svg() - @draw_path(@dates) - @draw_x_axis() - @draw_y_axis() - redraw: -> - @set_domain() - @svg.select("path").datum(@dates) - @svg.select("path").attr("d", @area) - @svg.select(".x.axis").call(@x_axis) - @svg.select(".y.axis").call(@y_axis) diff --git a/app/assets/javascripts/stat_graph_contributors_util.js.coffee b/app/assets/javascripts/stat_graph_contributors_util.js.coffee deleted file mode 100644 index 1670f5c7bc1916b6759b239ebc7380e6357662a3..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/stat_graph_contributors_util.js.coffee +++ /dev/null @@ -1,93 +0,0 @@ -window.ContributorsStatGraphUtil = - parse_log: (log) -> - total = {} - by_author = {} - for entry in log - @add_date(entry.date, total) unless total[entry.date]? - @add_author(entry, by_author) unless by_author[entry.author_name]? - @add_date(entry.date, by_author[entry.author_name]) unless by_author[entry.author_name][entry.date] - @store_data(entry, total[entry.date], by_author[entry.author_name][entry.date]) - total = _.toArray(total) - by_author = _.toArray(by_author) - total: total, by_author: by_author - - add_date: (date, collection) -> - collection[date] = {} - collection[date].date = date - - add_author: (author, by_author) -> - by_author[author.author_name] = {} - by_author[author.author_name].author_name = author.author_name - by_author[author.author_name].author_email = author.author_email - - store_data: (entry, total, by_author) -> - @store_commits(total, by_author) - @store_additions(entry, total, by_author) - @store_deletions(entry, total, by_author) - - store_commits: (total, by_author) -> - @add(total, "commits", 1) - @add(by_author, "commits", 1) - - add: (collection, field, value) -> - collection[field] ?= 0 - collection[field] += value - - store_additions: (entry, total, by_author) -> - entry.additions ?= 0 - @add(total, "additions", entry.additions) - @add(by_author, "additions", entry.additions) - - store_deletions: (entry, total, by_author) -> - entry.deletions ?= 0 - @add(total, "deletions", entry.deletions) - @add(by_author, "deletions", entry.deletions) - - get_total_data: (parsed_log, field) -> - log = parsed_log.total - total_data = @pick_field(log, field) - _.sortBy(total_data, (d) -> - d.date - ) - pick_field: (log, field) -> - total_data = [] - _.each(log, (d) -> - total_data.push(_.pick(d, [field, 'date'])) - ) - total_data - - get_author_data: (parsed_log, field, date_range = null) -> - log = parsed_log.by_author - author_data = [] - - _.each(log, (log_entry) => - parsed_log_entry = @parse_log_entry(log_entry, field, date_range) - if not _.isEmpty(parsed_log_entry.dates) - author_data.push(parsed_log_entry) - ) - - _.sortBy(author_data, (d) -> - d[field] - ).reverse() - - parse_log_entry: (log_entry, field, date_range) -> - parsed_entry = {} - parsed_entry.author_name = log_entry.author_name - parsed_entry.author_email = log_entry.author_email - parsed_entry.dates = {} - parsed_entry.commits = parsed_entry.additions = parsed_entry.deletions = 0 - _.each(_.omit(log_entry, 'author_name', 'author_email'), (value, key) => - if @in_range(value.date, date_range) - parsed_entry.dates[value.date] = value[field] - parsed_entry.commits += value.commits - parsed_entry.additions += value.additions - parsed_entry.deletions += value.deletions - ) - return parsed_entry - - in_range: (date, date_range) -> - if date_range is null || date_range[0] <= new Date(date) <= date_range[1] - true - else - false - diff --git a/app/assets/javascripts/subscription.js.coffee b/app/assets/javascripts/subscription.js.coffee deleted file mode 100644 index 7f41616d4e781fd4565cf4f657260c15edb338ee..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/subscription.js.coffee +++ /dev/null @@ -1,17 +0,0 @@ -class @Subscription - constructor: (url) -> - $(".subscribe-button").unbind("click").click (event)=> - btn = $(event.currentTarget) - action = btn.find("span").text() - current_status = $(".subscription-status").attr("data-status") - btn.prop("disabled", true) - - $.post url, => - btn.prop("disabled", false) - status = if current_status == "subscribed" then "unsubscribed" else "subscribed" - $(".subscription-status").attr("data-status", status) - action = if status == "subscribed" then "Unsubscribe" else "Subscribe" - btn.find("span").text(action) - $(".subscription-status>div").toggleClass("hidden") - - diff --git a/app/assets/javascripts/tree.js.coffee b/app/assets/javascripts/tree.js.coffee deleted file mode 100644 index d428db5b4227096ab1481fe345f6d4f764a49bb7..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/tree.js.coffee +++ /dev/null @@ -1,41 +0,0 @@ -class @TreeView - constructor: -> - @initKeyNav() - - # Code browser tree slider - # Make the entire tree-item row clickable, but not if clicking another link (like a commit message) - $(".tree-content-holder .tree-item").on 'click', (e) -> - if (e.target.nodeName != "A") - path = $('.tree-item-file-name a', this).attr('href') - Turbolinks.visit(path) - - # Show the "Loading commit data" for only the first element - $('span.log_loading:first').removeClass('hide') - - initKeyNav: -> - li = $("tr.tree-item") - liSelected = null - $('body').keydown (e) -> - if e.which is 40 - if liSelected - next = liSelected.next() - if next.length > 0 - liSelected.removeClass "selected" - liSelected = next.addClass("selected") - else - liSelected = li.eq(0).addClass("selected") - - $(liSelected).focus() - else if e.which is 38 - if liSelected - next = liSelected.prev() - if next.length > 0 - liSelected.removeClass "selected" - liSelected = next.addClass("selected") - else - liSelected = li.last().addClass("selected") - - $(liSelected).focus() - else if e.which is 13 - path = $('.tree-item.selected .tree-item-file-name a').attr('href') - Turbolinks.visit(path) diff --git a/app/assets/javascripts/user.js.coffee b/app/assets/javascripts/user.js.coffee deleted file mode 100644 index d0d81f96921ac16630670b69567ae2ec61cee224..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/user.js.coffee +++ /dev/null @@ -1,4 +0,0 @@ -class @User - constructor: -> - $('.profile-groups-avatars').tooltip("placement": "top") - new ProjectsList() diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee deleted file mode 100644 index aeeed9ca3ccaa55299ba3023d28b5b05ec57e2ab..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/users_select.js.coffee +++ /dev/null @@ -1,117 +0,0 @@ -class @UsersSelect - constructor: -> - @usersPath = "/autocomplete/users.json" - @userPath = "/autocomplete/users/:id.json" - - $('.ajax-users-select').each (i, select) => - @projectId = $(select).data('project-id') - @groupId = $(select).data('group-id') - showNullUser = $(select).data('null-user') - showAnyUser = $(select).data('any-user') - showEmailUser = $(select).data('email-user') - firstUser = $(select).data('first-user') - - $(select).select2 - placeholder: "Search for a user" - multiple: $(select).hasClass('multiselect') - minimumInputLength: 0 - query: (query) => - @users query.term, (users) => - data = { results: users } - - if query.term.length == 0 - if firstUser - # Move current user to the front of the list - for obj, index in data.results - if obj.username == firstUser - data.results.splice(index, 1) - data.results.unshift(obj) - break - - if showNullUser - nullUser = { - name: 'Unassigned', - avatar: null, - username: 'none', - id: 0 - } - data.results.unshift(nullUser) - - if showAnyUser - anyUser = { - name: 'Any', - avatar: null, - username: 'none', - id: null - } - data.results.unshift(anyUser) - - if showEmailUser && data.results.length == 0 && query.term.match(/^[^@]+@[^@]+$/) - emailUser = { - name: "Invite \"#{query.term}\"", - avatar: null, - username: query.term, - id: query.term - } - data.results.unshift(emailUser) - - query.callback(data) - - initSelection: (element, callback) => - id = $(element).val() - if id != "" && id != "0" - @user(id, callback) - - formatResult: (args...) => - @formatResult(args...) - formatSelection: (args...) => - @formatSelection(args...) - dropdownCssClass: "ajax-users-dropdown" - escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results - m - - formatResult: (user) -> - if user.avatar_url - avatar = user.avatar_url - else - avatar = gon.default_avatar_url - - "
    -
    -
    #{user.name}
    -
    #{user.username}
    -
    " - - formatSelection: (user) -> - user.name - - user: (user_id, callback) => - url = @buildUrl(@userPath) - url = url.replace(':id', user_id) - - $.ajax( - url: url - dataType: "json" - ).done (user) -> - callback(user) - - # Return users list. Filtered by query - # Only active users retrieved - users: (query, callback) => - url = @buildUrl(@usersPath) - - $.ajax( - url: url - data: - search: query - per_page: 20 - active: true - project_id: @projectId - group_id: @groupId - dataType: "json" - ).done (users) -> - callback(users) - - buildUrl: (url) -> - url = gon.relative_url_root + url if gon.relative_url_root? - return url diff --git a/app/assets/javascripts/wikis.js.coffee b/app/assets/javascripts/wikis.js.coffee deleted file mode 100644 index 66757565d3aae583405e2e6ef1aebc5602cad83c..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/wikis.js.coffee +++ /dev/null @@ -1,9 +0,0 @@ -class @Wikis - constructor: -> - $('.build-new-wiki').bind "click", -> - field = $('#new_wiki_path') - slug = field.val() - path = field.attr('data-wikis-path') - - if(slug.length > 0) - location.href = path + "/" + slug diff --git a/app/assets/javascripts/zen_mode.js.coffee b/app/assets/javascripts/zen_mode.js.coffee deleted file mode 100644 index 0fb8f7ed75fdd4c6d691d1901a173cfa00f41835..0000000000000000000000000000000000000000 --- a/app/assets/javascripts/zen_mode.js.coffee +++ /dev/null @@ -1,67 +0,0 @@ -class @ZenMode - @fullscreen_prefix = 'fullscreen_' - - constructor: -> - @active_zen_area = null - @active_checkbox = null - @scroll_position = 0 - - $(window).scroll => - if not @active_checkbox - @scroll_position = window.pageYOffset - - $('body').on 'click', '.zen-enter-link', (e) => - e.preventDefault() - $(e.currentTarget).closest('.zennable').find('.zen-toggle-comment').prop('checked', true) - - $('body').on 'click', '.zen-leave-link', (e) => - e.preventDefault() - $(e.currentTarget).closest('.zennable').find('.zen-toggle-comment').prop('checked', false) - - $('body').on 'change', '.zen-toggle-comment', (e) => - checkbox = e.currentTarget - if checkbox.checked - # Disable other keyboard shortcuts in ZEN mode - Mousetrap.pause() - @udpateActiveZenArea(checkbox) - else - @exitZenMode() - - $(document).on 'keydown', (e) => - if e.keyCode is $.ui.keyCode.ESCAPE - @exitZenMode() - e.preventDefault() - - $(window).on 'hashchange', @updateZenModeFromLocationHash - - udpateActiveZenArea: (checkbox) => - @active_checkbox = $(checkbox) - @active_checkbox.prop('checked', true) - @active_zen_area = @active_checkbox.parent().find('textarea') - @active_zen_area.focus() - window.location.hash = ZenMode.fullscreen_prefix + @active_checkbox.prop('id') - - exitZenMode: => - if @active_zen_area isnt null - Mousetrap.unpause() - @active_checkbox.prop('checked', false) - @active_zen_area = null - @active_checkbox = null - window.location.hash = '' - window.scrollTo(window.pageXOffset, @scroll_position) - # Enable dropzone when leaving ZEN mode - Dropzone.forElement('.div-dropzone').enable() - - checkboxFromLocationHash: (e) -> - id = $.trim(window.location.hash.replace('#' + ZenMode.fullscreen_prefix, '')) - if id - return $('.zennable input[type=checkbox]#' + id)[0] - else - return null - - updateZenModeFromLocationHash: (e) => - checkbox = @checkboxFromLocationHash() - if checkbox - @udpateActiveZenArea(checkbox) - else - @exitZenMode() diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss deleted file mode 100644 index 015ff2ce4ec71826c58378c451f3a342e01cc737..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/application.scss +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This is a manifest file that'll automatically include all the stylesheets available in this directory - * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at - * the top of the compiled file, but it's generally better to create a new file per style scope. - *= require jquery.ui.datepicker - *= require jquery.ui.autocomplete - *= require jquery.atwho - *= require select2 - *= require_self - *= require dropzone/basic - *= require cal-heatmap -*/ - - -@import "base/variables"; -@import "base/mixins"; -@import "base/layout"; - - -/** - * Customized Twitter bootstrap - */ -@import 'base/gl_variables'; -@import 'base/gl_bootstrap'; - -/** - * NProgress load bar css - */ -@import 'nprogress'; -@import 'nprogress-bootstrap'; - -/** - * Font icons - * - */ -@import "font-awesome"; - -/** - * Generic css (forms, nav etc): - */ -@import "generic/*"; - -/** - * Page specific styles (issues, projects etc): - */ - -@import "pages/*"; - -/** - * Code highlight - */ -@import "highlight/*"; - -/** - * UI themes: - */ -@import "themes/*"; - -/** - * Styles for JS behaviors. - */ -@import "behaviors.scss"; diff --git a/app/assets/stylesheets/base/gl_bootstrap.scss b/app/assets/stylesheets/base/gl_bootstrap.scss deleted file mode 100644 index 62a3eade5c73a4c54eaf297e1722d54eb0d61323..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/base/gl_bootstrap.scss +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Twitter bootstrap with GitLab customizations/additions - * - */ - -// Core variables and mixins -@import "bootstrap/variables"; -@import "bootstrap/mixins"; - -// Reset -@import "bootstrap/normalize"; -@import "bootstrap/print"; - -// Core CSS -@import "bootstrap/scaffolding"; -@import "bootstrap/type"; -@import "bootstrap/code"; -@import "bootstrap/grid"; -@import "bootstrap/tables"; -@import "bootstrap/forms"; -@import "bootstrap/buttons"; - -// Components -@import "bootstrap/component-animations"; -@import "bootstrap/dropdowns"; -@import "bootstrap/button-groups"; -@import "bootstrap/input-groups"; -@import "bootstrap/navs"; -@import "bootstrap/navbar"; -@import "bootstrap/breadcrumbs"; -@import "bootstrap/pagination"; -@import "bootstrap/pager"; -@import "bootstrap/labels"; -@import "bootstrap/badges"; -@import "bootstrap/jumbotron"; -@import "bootstrap/thumbnails"; -@import "bootstrap/alerts"; -@import "bootstrap/progress-bars"; -@import "bootstrap/list-group"; -@import "bootstrap/wells"; -@import "bootstrap/close"; -@import "bootstrap/panels"; - -// Components w/ JavaScript -@import "bootstrap/modals"; -@import "bootstrap/tooltip"; -@import "bootstrap/popovers"; -@import "bootstrap/carousel"; - -// Utility classes -.clearfix { - @include clearfix(); -} -.center-block { - @include center-block(); -} -.pull-right { - float: right !important; -} -.pull-left { - float: left !important; -} -.hide { - display: none; -} -.show { - display: block !important; -} -.invisible { - visibility: hidden; -} -.text-hide { - @include text-hide(); -} -.hidden { - display: none !important; - visibility: hidden !important; -} -.affix { - position: fixed; -} - -@import "bootstrap/responsive-utilities"; - -// Labels -.label { - padding: 2px 4px; - font-size: 12px; - font-style: normal; - font-weight: normal; - display: inline-block; - - &.label-gray { - background-color: #eee; - color: #999; - text-shadow: none; - } - - &.label-inverse { - background-color: #333333; - } -} - -// Nav tabs -.nav.nav-tabs { - margin-bottom: 15px; - - li { - > a { - margin-right: 5px; - line-height: 20px; - border-color: #EEE; - color: #888; - border-bottom: 1px solid #ddd; - .badge { - background-color: #eee; - color: #888; - text-shadow: 0 1px 1px #fff; - } - i[class~="fa"] { - line-height: 14px; - } - } - &.active { - > a { - border-color: #CCC; - border-bottom: 1px solid #fff; - color: #333; - font-weight: bold; - } - } - } -} - -.nav-tabs > li > a, -.nav-pills > li > a { - color: #666; -} - -/** - * fix to keep tooltips position in top navigation bar - * - */ -.navbar .nav > li { - position: relative; - white-space: nowrap; -} - -/** - * Add some extra stuff to panels - * - */ -.panel { - .panel-heading { - font-weight: bold; - - .panel-head-actions { - position: relative; - top: -5px; - float: right; - } - } - - .panel-body { - form { - margin: 0; - } - - .form-actions { - margin: -15px; - margin-top: 18px; - } - } - - .panel-footer { - .pagination { - margin: 0; - } - } - - &.panel-small { - .panel-heading { - padding: 6px 15px; - font-size: 13px; - font-weight: normal; - a { - color: #777; - } - } - } -} - -.panel-succes .panel-heading, -.panel-info .panel-heading, -.panel-danger .panel-heading, -.panel-warning .panel-heading, -.panel-primary .panel-heading, -.alert { - a:not(.btn) { - @extend .alert-link; - color: #fff; - text-decoration: underline; - } -} - -// Typography ================================================================= - -.text-primary, -.text-primary:hover { - color: $brand-primary; -} - -.text-success, -.text-success:hover { - color: $brand-success; -} - -.text-danger, -.text-danger:hover { - color: $brand-danger; -} - -.text-warning, -.text-warning:hover { - color: $brand-warning; -} - -.text-info, -.text-info:hover { - color: $brand-info; -} - -// Tables ===================================================================== - -table.table { - .dropdown-menu a { - text-decoration: none; - } - - .success, - .warning, - .danger, - .info { - color: #fff; - - a:not(.btn) { - text-decoration: underline; - color: #fff; - } - } -} diff --git a/app/assets/stylesheets/base/gl_variables.scss b/app/assets/stylesheets/base/gl_variables.scss deleted file mode 100644 index 56f4c794e1b3c00109334a521a3b97366f8b5653..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/base/gl_variables.scss +++ /dev/null @@ -1,133 +0,0 @@ -// Override Bootstrap variables here (defaults from bootstrap-sass v3.3.3): -// For all variables see https://github.com/twbs/bootstrap-sass/blob/master/templates/project/_bootstrap-variables.sass -// -// Variables -// -------------------------------------------------- - - -//== Colors -// -//## Gray and brand colors for use across Bootstrap. - -// $gray-base: #000 -// $gray-darker: lighten($gray-base, 13.5%) // #222 -// $gray-dark: lighten($gray-base, 20%) // #333 -// $gray: lighten($gray-base, 33.5%) // #555 -// $gray-light: lighten($gray-base, 46.7%) // #777 -// $gray-lighter: lighten($gray-base, 93.5%) // #eee - -$brand-primary: $gl-primary; -$brand-success: $gl-success; -$brand-info: $gl-info; -$brand-warning: $gl-warning; -$brand-danger: $gl-danger; - - -//== Scaffolding -// -$text-color: $gl-text-color; -$link-color: $gl-link-color; - - -//== Typography -// -//## Font, line-height, and color for body text, headings, and more. - -$font-family-sans-serif: $regular_font; -$font-family-monospace: $monospace_font; -$font-size-base: $gl-font-size; - - -//== Components -// -//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start). - -$padding-base-vertical: 6px; -$padding-base-horizontal: 14px; - - -//== Forms -// -//## - -$input-color: $text-color; -$input-border: #DDD; -$input-border-focus: $brand-info; -$legend-color: $text-color; - - -//== Pagination -// -//## - -$pagination-color: #fff; -$pagination-bg: $brand-success; -$pagination-border: transparent; - -$pagination-hover-color: #fff; -$pagination-hover-bg: darken($brand-success, 15%); -$pagination-hover-border: transparent; - -$pagination-active-color: #fff; -$pagination-active-bg: darken($brand-success, 15%); -$pagination-active-border: transparent; - -$pagination-disabled-color: #b4bcc2; -$pagination-disabled-bg: lighten($brand-success, 15%); -$pagination-disabled-border: transparent; - - -//== Form states and alerts -// -//## Define colors for form feedback states and, by default, alerts. - -$state-success-text: #fff; -$state-success-bg: $brand-success; -$state-success-border: $brand-success; - -$state-info-text: #fff; -$state-info-bg: $brand-info; -$state-info-border: $brand-info; - -$state-warning-text: #fff; -$state-warning-bg: $brand-warning; -$state-warning-border: $brand-warning; - -$state-danger-text: #fff; -$state-danger-bg: $brand-danger; -$state-danger-border: $brand-danger; - - -//== Alerts -// -//## Define alert colors, border radius, and padding. - -$alert-border-radius: 0; - - -//== Panels -// -//## - -$panel-border-radius: 0; -$panel-default-text: $text-color; -$panel-default-border: $border-color; -$panel-default-heading-bg: $background-color; - - -//== Wells -// -//## - -$well-bg: #F9F9F9; -$well-border: #EEE; - -//== Code -// -//## - -$code-color: #c7254e; -$code-bg: #f9f2f4; - -$kbd-color: #fff; -$kbd-bg: #333; diff --git a/app/assets/stylesheets/base/layout.scss b/app/assets/stylesheets/base/layout.scss deleted file mode 100644 index 62c11b06368dd66cbd051f47ae89ee69c75b1e41..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/base/layout.scss +++ /dev/null @@ -1,22 +0,0 @@ -html { - overflow-y: scroll; - - &.touch .tooltip { display: none !important; } - - body { - padding-top: 46px; - } -} - -.container { - padding-top: 0; - z-index: 5; -} - -.container .content { - margin: 0 0; -} - -.navless-container { - margin-top: 30px; -} diff --git a/app/assets/stylesheets/base/mixins.scss b/app/assets/stylesheets/base/mixins.scss deleted file mode 100644 index 216f25cdcd531abfd53c8e871f478ab453f03a62..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/base/mixins.scss +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Generic mixins - */ - @mixin box-shadow($shadow) { - -webkit-box-shadow: $shadow; - -moz-box-shadow: $shadow; - -ms-box-shadow: $shadow; - -o-box-shadow: $shadow; - box-shadow: $shadow; -} - -@mixin border-radius($radius) { - -webkit-border-radius: $radius; - -moz-border-radius: $radius; - -ms-border-radius: $radius; - -o-border-radius: $radius; - border-radius: $radius; -} - -@mixin border-radius-left($radius) { - @include border-radius($radius 0 0 $radius) -} - -@mixin linear-gradient($from, $to) { - background-image: -webkit-gradient(linear, 0 0, 0 100%, from($from), to($to)); - background-image: -webkit-linear-gradient($from, $to); - background-image: -moz-linear-gradient($from, $to); - background-image: -ms-linear-gradient($from, $to); - background-image: -o-linear-gradient($from, $to); -} - -@mixin transition($transition) { - -webkit-transition: $transition; - -moz-transition: $transition; - -ms-transition: $transition; - -o-transition: $transition; - transition: $transition; -} - -/** - * Prefilled mixins - * Mixins with fixed values - */ - -@mixin shade { - @include box-shadow(0 0 3px #ddd); -} - -@mixin solid-shade { - @include box-shadow(0 0 0 3px #f1f1f1); -} - -@mixin header-font { - color: $style_color; - font-size: 16px; - line-height: 44px; - font-weight: normal; -} - -@mixin md-typography { - font-size: 15px; - line-height: 1.5; - - img { - max-width: 100%; - } - - *:first-child { - margin-top: 0; - } - - code { - font-family: $monospace_font; - white-space: pre; - word-wrap: normal; - padding: 0; - } - - h1 { - margin-top: 45px; - font-size: 2.5em; - } - - h2 { - margin-top: 40px; - font-size: 2em; - } - - h3 { - margin-top: 35px; - font-size: 1.5em; - } - - h4 { - margin-top: 30px; - font-size: 1.2em; - } - - blockquote p { - color: #888; - font-size: 15px; - line-height: 1.5; - } - - table { - @extend .table; - @extend .table-bordered; - th { - background: #EEE; - } - } - - p > code { - font-size: inherit; - font-weight: inherit; - color: #555; - } - - li { - line-height: 1.5; - } - - a[href*="/uploads/"], a[href*="storage.googleapis.com/google-code-attachments/"] { - &:before { - margin-right: 4px; - - font: normal normal normal 14px/1 FontAwesome; - font-size: inherit; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - content: "\f0c6"; - } - - &:hover:before { - text-decoration: none; - } - } -} - -@mixin str-truncated($max_width: 82%) { - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - vertical-align: top; - white-space: nowrap; - max-width: $max_width; -} diff --git a/app/assets/stylesheets/base/variables.scss b/app/assets/stylesheets/base/variables.scss deleted file mode 100644 index 596376c3970b84e77d7ee414cd491f5ef08cc252..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/base/variables.scss +++ /dev/null @@ -1,34 +0,0 @@ -$style_color: #474D57; -$hover: #FFF3EB; -$gl-text-color: #222222; -$gl-link-color: #446e9b; -$nprogress-color: #c0392b; -$gl-font-size: 14px; -$list-font-size: 15px; -$sidebar_width: 230px; -$avatar_radius: 50%; -$code_font_size: 13px; -$code_line_height: 1.5; -$border-color: #E5E5E5; -$background-color: #f5f5f5; - -/* - * State colors: - */ -$gl-primary: #446e9b; -$gl-success: #019875; -$gl-info: #029ACF; -$gl-warning: #EB9532; -$gl-danger: #d9534f; - -/* - * Commit Diff Colors - */ -$added: #63c363; -$deleted: #f77; - -/* - * Fonts - */ -$monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace; -$regular_font: "Helvetica Neue", Helvetica, Arial, sans-serif; diff --git a/app/assets/stylesheets/behaviors.scss b/app/assets/stylesheets/behaviors.scss deleted file mode 100644 index 469f4f296ae6e1ebe6b9a6e1dd2d5d961cc0b82d..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/behaviors.scss +++ /dev/null @@ -1,22 +0,0 @@ -// Details -//-------- -.js-details-container { - .content { - display: none; - &.hide { display: block; } - } - &.open .content { - display: block; - &.hide { display: none; } - } -} - -// Toggle between two states. -.js-toggler-container { - .turn-on { display: block; } - .turn-off { display: none; } - &.on { - .turn-on { display: none; } - .turn-off { display: block; } - } -} diff --git a/app/assets/stylesheets/generic/avatar.scss b/app/assets/stylesheets/generic/avatar.scss deleted file mode 100644 index 8595887c3b9cd1877f697b644b330fb895633c26..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/avatar.scss +++ /dev/null @@ -1,42 +0,0 @@ -.avatar { - float: left; - margin-right: 12px; - width: 40px; - height: 40px; - padding: 0; - @include border-radius($avatar_radius); - - &.avatar-inline { - float: none; - margin-left: 4px; - margin-bottom: 2px; - - &.s16 { margin-right: 4px; } - &.s24 { margin-right: 4px; } - } - - &.group-avatar, &.project-avatar, &.avatar-tile { - @include border-radius(0px); - } - - &.s16 { width: 16px; height: 16px; margin-right: 6px; } - &.s24 { width: 24px; height: 24px; margin-right: 8px; } - &.s26 { width: 26px; height: 26px; margin-right: 8px; } - &.s32 { width: 32px; height: 32px; margin-right: 10px; } - &.s60 { width: 60px; height: 60px; margin-right: 12px; } - &.s90 { width: 90px; height: 90px; margin-right: 15px; } - &.s160 { width: 160px; height: 160px; margin-right: 20px; } -} - -.identicon { - text-align: center; - vertical-align: top; - - &.s16 { font-size: 12px; line-height: 1.33; } - &.s24 { font-size: 14px; line-height: 1.8; } - &.s26 { font-size: 20px; line-height: 1.33; } - &.s32 { font-size: 22px; line-height: 32px; } - &.s60 { font-size: 32px; line-height: 60px; } - &.s90 { font-size: 36px; line-height: 90px; } - &.s160 { font-size: 96px; line-height: 1.33; } -} diff --git a/app/assets/stylesheets/generic/blocks.scss b/app/assets/stylesheets/generic/blocks.scss deleted file mode 100644 index 3536a68f416fc335177d27f763bdb77207a2f523..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/blocks.scss +++ /dev/null @@ -1,19 +0,0 @@ -.light-well { - background: #f9f9f9; - padding: 15px; -} - -.centered-light-block { - text-align: center; - color: #888; - margin: 20px; -} - -.nothing-here-block { - text-align: center; - padding: 20px; - color: #666; - font-weight: normal; - font-size: 16px; - line-height: 36px; -} diff --git a/app/assets/stylesheets/generic/buttons.scss b/app/assets/stylesheets/generic/buttons.scss deleted file mode 100644 index cd6bf64c0ae2c8c6bbb79992028da0129367aa19..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/buttons.scss +++ /dev/null @@ -1,74 +0,0 @@ -.btn { - @extend .btn-default; - - &.btn-new { - @extend .btn-success; - } - - &.btn-create { - @extend .btn-success; - } - - &.btn-save { - @extend .btn-primary; - } - - &.btn-remove { - @extend .btn-danger; - } - - &.btn-cancel { - float: right; - } - - &.btn-close { - color: $gl-danger; - border-color: $gl-danger; - &:hover { - color: #B94A48; - } - } - - &.btn-reopen { - color: $gl-success; - border-color: $gl-success; - &:hover { - color: #468847; - } - } - - &.btn-grouped { - margin-right: 7px; - float: left; - &:last-child { - margin-right: 0px; - } - } - - &.btn-save { - @extend .btn-primary; - } - - &.btn-new, &.btn-create { - @extend .btn-success; - } -} - -.btn-block { - width: 100%; - margin: 0; - margin-bottom: 15px; - &.btn { - padding: 6px 0; - } -} - -.btn-group { - &.btn-grouped { - margin-right: 7px; - float: left; - &:last-child { - margin-right: 0px; - } - } -} diff --git a/app/assets/stylesheets/generic/calendar.scss b/app/assets/stylesheets/generic/calendar.scss deleted file mode 100644 index a36fefe22c54fe644b65bf256c8fe82ec46044e0..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/calendar.scss +++ /dev/null @@ -1,90 +0,0 @@ -.user-calendar-activities { - .calendar_onclick_hr { - padding: 0; - margin: 10px 0; - } - - .str-truncated { - max-width: 70%; - } - - .text-expander { - background: #eee; - color: #555; - padding: 0 5px; - cursor: pointer; - margin-left: 4px; - &:hover { - background-color: #ddd; - } - } -} -/** -* This overwrites the default values of the cal-heatmap gem -*/ -.calendar { - .qi { - background-color: #999; - fill: #fff; - } - - .q1 { - background-color: #dae289; - fill: #ededed; - } - - .q2 { - background-color: #cedb9c; - fill: #ACD5F2; - } - - .q3 { - background-color: #b5cf6b; - fill: #7FA8D1; - } - - .q4 { - background-color: #637939; - fill: #49729B; - } - - .q5 { - background-color: #3b6427; - fill: #254E77; - } - - .domain-background { - fill: none; - shape-rendering: crispedges; - } - - .ch-tooltip { - position: absolute; - display: none; - margin-top: 22px; - margin-left: 1px; - font-size: 13px; - padding: 3px; - font-weight: 550; - background-color: #222; - span { - position: absolute; - width: 200px; - text-align: center; - visibility: hidden; - border-radius: 10px; - &:after { - content: ''; - position: absolute; - top: 100%; - left: 50%; - margin-left: -8px; - width: 0; - height: 0; - border-top: 8px solid #000000; - border-right: 8px solid transparent; - border-left: 8px solid transparent; - } - } - } -} diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss deleted file mode 100644 index 7c3021989a87628d6e502c366077c20216f2aee4..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/common.scss +++ /dev/null @@ -1,376 +0,0 @@ -/** COLORS **/ -.cgray { color: gray } -.clgray { color: #BBB } -.cred { color: #D12F19 } -.cgreen { color: #4a2 } -.cdark { color: #444 } - -/** COMMON CLASSES **/ -.prepend-top-10 { margin-top:10px } -.prepend-top-20 { margin-top:20px } -.prepend-left-10 { margin-left:10px } -.prepend-left-20 { margin-left:20px } -.append-right-10 { margin-right:10px } -.append-right-20 { margin-right:20px } -.append-bottom-10 { margin-bottom:10px } -.append-bottom-15 { margin-bottom:15px } -.append-bottom-20 { margin-bottom:20px } -.inline { display: inline-block } -.center { text-align: center } - -.underlined-link { text-decoration: underline; } -.hint { font-style: italic; color: #999; } -.light { color: #888 } - -.slead { - color: #666; - font-size: 15px; - margin-bottom: 12px; - font-weight: normal; - line-height: 24px; -} - -.tab-content { - overflow: visible; -} - -pre { - &.clean { - background: none; - border: none; - margin: 0; - padding: 0; - } - - &.well-pre { - border: 1px solid #EEE; - background: #f9f9f9; - border-radius: 0; - color: #555; - } -} - -.dropdown-menu > li > a { - text-shadow: none; -} - -.dropdown-menu-align-right { - left: auto; - right: 0px; -} - -.dropdown-menu > li > a:hover, -.dropdown-menu > li > a:focus { - background: $gl-primary; - color: #FFF -} - -.str-truncated { - @include str-truncated; -} - -/** FLASH message **/ -.author_link { - color: $gl-link-color; -} - -.help li { color:$style_color; } - -.back-link { - font-size: 14px; -} - -table a code { - position: relative; - top: -2px; - margin-right: 3px; -} - -.loading { - margin: 20px auto; - height: 40px; - color: #555; - font-size: 32px; - text-align: center; -} - -span.update-author { - display: block; - color: #999; - font-weight: normal; - font-style: italic; - strong { - font-weight: bold; - font-style: normal; - } -} - -.user-mention { - color: #2FA0BB; - font-weight: bold; -} - -.field_with_errors { - display: inline; -} - -.line_holder { - &:hover { - td { - background: #FFFFCF !important; - } - } -} - -p.time { - color: #999; - font-size: 90%; - margin: 30px 3px 3px 2px; -} - -.highlight { - text-shadow: none; -} - -.highlight_word { - background: #fafe3d; -} - -.thin_area{ - height: 150px; -} - -// Fixes alignment on notes. -.new_note { - label { - text-align: left; - } -} - -// Fix issue with notes & lists creating a bunch of bottom borders. -li.note { - img { max-width:100% } - .note-title { - li { - border-bottom:none !important; - } - } -} - -.markdown { - img { - max-width: 100%; - } -} - -.wiki_content code, .readme code{ - background-color: inherit; -} - -.project_member_show { - td:first-child { - color: #aaa; - } -} - -.rss-icon { - img { - width: 24px; - vertical-align: top; - } - - strong { - line-height: 24px; - } -} - -.supp_diff_link, -.show-all-commits { - cursor: pointer; -} - -.git_error_tips { - @extend .col-md-6; - text-align: left; - margin-top: 40px; - pre { - background: white; - border: none; - font-size: 12px; - } -} - -.error-message { - padding: 10px; - background: #C67; - margin: 0; - color: #FFF; - - a { - color: #fff; - text-decoration: underline; - } -} - -.browser-alert { - padding: 10px; - text-align: center; - background: #C67; - color: #fff; - font-weight: bold; - a { - color: #fff; - text-decoration: underline; - } -} - -.warning_message { - border-left: 4px solid #ed9; - color: #b90; - padding: 10px; - margin-bottom: 10px; - background: #ffffe6; - padding-left: 20px; - - &.centered { - text-align: center; - } -} - -.gitlab-promo { - a { - color: #aaa; - margin-right: 30px; - } -} - -.milestone { - &.milestone-closed { - background: #f9f9f9; - } - .progress { - margin-bottom: 0; - margin-top: 4px; - } -} - -.control-group { - .controls { - span { - &.descr { - position: relative; - top: 2px; - left: 5px; - color: #666; - } - } - } -} - -img.emoji { - height: 20px; - vertical-align: middle; - width: 20px; -} - -.chart { - overflow: hidden; - height: 220px; -} - -.description-block { - @extend .light-well; - @extend .light; - margin-bottom: 10px; -} - -table { - td.permission-x { - background: #D9EDF7 !important; - text-align: center; - } -} - -.dashboard-intro-icon { - float: left; - text-align: center; - font-size: 32px; - color: #AAA; - width: 60px; -} - -.dashboard-intro-text { - display: inline-block; - margin-left: -60px; - padding-left: 60px; - width: 100%; -} - -.btn-sign-in { - margin-top: 5px; - text-shadow: none; -} - -.side-filters { - fieldset { - margin-bottom: 15px; - } -} - -.wiki .highlight, .note-body .highlight { - margin-bottom: 9px; -} - -.wiki .code { - overflow-x: auto; -} - -.footer-links { - margin-bottom: 20px; - a { - margin-right: 15px; - } -} - -.search_box { - position: relative; - padding: 30px; - text-align: center; - background-color: #F9F9F9; - border: 1px solid #DDDDDD; - border-radius: 0px; -} - -.search_glyph { - color: #555; - font-size: 42px; -} - -.task-status { - margin-left: 10px; -} - -#nprogress .spinner { - top: auto !important; - bottom: 20px !important; - left: 20px !important; -} - -.header-with-avatar { - h3 { - margin: 0; - font-weight: bold; - } - - .username { - font-size: 18px; - color: #666; - margin-top: 8px; - } - - .description { - font-size: 16px; - color: #666; - margin-top: 8px; - } -} diff --git a/app/assets/stylesheets/generic/files.scss b/app/assets/stylesheets/generic/files.scss deleted file mode 100644 index 8014dcb165b3845864715670d6e34340fded5f48..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/files.scss +++ /dev/null @@ -1,145 +0,0 @@ -/** - * File content holder - * - */ -.file-holder { - border: 1px solid $border-color; - margin-bottom: 1em; - - table { - @extend .table; - } - - .file-title { - position: relative; - background: $background-color; - border-bottom: 1px solid $border-color; - text-shadow: 0 1px 1px #fff; - margin: 0; - text-align: left; - padding: 10px 15px; - - .file-actions { - float: right; - position: absolute; - top: 5px; - right: 15px; - - .btn { - padding: 0px 10px; - font-size: 13px; - line-height: 28px; - } - } - - .left-options { - margin-top: -3px; - } - } - .file-content { - background: #fff; - - &.image_file { - background: #eee; - text-align: center; - img { - padding: 100px; - max-width: 50%; - } - } - - &.wiki { - padding: 25px; - - .highlight { - margin-bottom: 9px; - - > pre { - margin: 0; - } - } - } - - &.blob_file { - - } - - &.blob-no-preview { - background: #eee; - text-shadow: 0 1px 2px #FFF; - padding: 100px 0; - } - - /** - * Blame file - */ - &.blame { - table { - border: none; - box-shadow: none; - margin: 0; - } - tr { - border-bottom: 1px solid #eee; - } - td { - &:first-child { - border-left: none; - } - &:last-child { - border-right: none; - } - background: #fff; - padding: 5px; - } - .author, - .blame_commit { - background: $background-color; - vertical-align: top; - } - .lines { - pre { - padding: 0; - margin: 0; - background: none; - border: none; - } - } - } - - &.logs { - background: #eee; - max-height: 700px; - overflow-y: auto; - - ol { - margin-left: 40px; - padding: 10px 0; - border-left: 1px solid $border-color; - margin-bottom: 0; - background: white; - li { - color: #888; - p { - margin: 0; - color: #333; - line-height: 24px; - padding-left: 10px; - } - - &:hover { - background: $hover; - } - } - } - } - - /** - * Code file - */ - &.code { - padding: 0; - } - } -} - diff --git a/app/assets/stylesheets/generic/filters.scss b/app/assets/stylesheets/generic/filters.scss deleted file mode 100644 index bd93a79722dd5a3b58aead122628b91c0e9b99fb..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/filters.scss +++ /dev/null @@ -1,55 +0,0 @@ -.filter-item { - margin-right: 15px; -} - -.issues-state-filters { - li.active a { - border-color: #DDD !important; - - &, &:hover, &:active, &.active { - background: #f5f5f5 !important; - border-bottom: 1px solid #f5f5f5 !important; - } - } -} - -.issues-details-filters { - font-size: 13px; - background: #f5f5f5; - margin: -10px 0; - padding: 10px 15px; - margin-top: -15px; - border-left: 1px solid #DDD; - border-right: 1px solid #DDD; - - .btn { - font-size: 13px; - } -} - -@media (min-width: 800px) { - .issues-filters, - .issues_bulk_update { - select, .select2-container { - width: 120px !important; - display: inline-block; - } - } -} - -@media (min-width: 1200px) { - .issues-filters, - .issues_bulk_update { - select, .select2-container { - width: 150px !important; - display: inline-block; - } - } -} - -.issues-filters, -.issues_bulk_update { - .select2-container .select2-choice { - color: #444 !important; - } -} diff --git a/app/assets/stylesheets/generic/flash.scss b/app/assets/stylesheets/generic/flash.scss deleted file mode 100644 index 82eb50ad4be068473bac0507f6fc1a1aa75750b0..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/flash.scss +++ /dev/null @@ -1,17 +0,0 @@ -.flash-container { - cursor: pointer; - margin: 0; - font-size: 14px; - width: 100%; - z-index: 100; - - .flash-notice { - @extend .alert; - @extend .alert-info; - } - - .flash-alert { - @extend .alert; - @extend .alert-danger; - } -} diff --git a/app/assets/stylesheets/generic/forms.scss b/app/assets/stylesheets/generic/forms.scss deleted file mode 100644 index 266041403e06188e30ab24d15e7a6e36cadb99b8..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/forms.scss +++ /dev/null @@ -1,95 +0,0 @@ -textarea { - resize: vertical; -} - -input[type='search'].search-text-input { - background-image: image-url("icon-search.png"); - background-repeat: no-repeat; - background-position: 10px; - padding-left: 25px; -} - -input[type='text'].danger { - background: #F2DEDE!important; - border-color: #D66; - text-shadow: 0 1px 1px #fff -} - -.datetime-controls { - select { - width: 100px; - } -} - -.form-actions { - padding: 17px 20px 18px; - margin-top: 18px; - margin-bottom: 18px; - background-color: $background-color; - border-top: 1px solid $border-color; -} - -@media (min-width: $screen-sm-min) { - .form-actions { - padding-left: 17%; - } -} - -label { - &.control-label { - @extend .col-sm-2; - } - - &.inline-label { - margin: 0; - } -} - -.inline-input-group { - width: 250px; -} - -.input-mx-250 { - max-width: 250px; -} - -.input-mn-300 { - min-width: 300px; -} - -.custom-form-control { - width: 150px; -} - -@media (min-width: $screen-sm-min) { - .custom-form-control { - width: 150px; - } -} - -/* Medium devices (desktops, 992px and up) */ -@media (min-width: $screen-md-min) { - .custom-form-control { - width: 170px; - } -} - -/* Large devices (large desktops, 1200px and up) */ -@media (min-width: $screen-lg-min) { - .custom-form-control { - width: 200px; - } -} - -.fieldset-form fieldset { - margin-bottom: 20px; -} - -.form-control { - @include box-shadow(none); -} - -.issuable-description, -.wiki-content { - margin-top: 35px; -} diff --git a/app/assets/stylesheets/generic/gfm.scss b/app/assets/stylesheets/generic/gfm.scss deleted file mode 100644 index 8fac5e534fa9c17c227db2b1d7e4c991286cb7a4..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/gfm.scss +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Styles that apply to all GFM related forms. - */ -.issue-form, .merge-request-form, .wiki-form { - .description { - height: 16em; - border-top-left-radius: 0; - } -} - -.wiki-form { - .description { - height: 26em; - } -} - -.milestone-form { - .description { - height: 14em; - } -} diff --git a/app/assets/stylesheets/generic/highlight.scss b/app/assets/stylesheets/generic/highlight.scss deleted file mode 100644 index 2e13ee842e0178c72cf0508aa106ca658906dc84..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/highlight.scss +++ /dev/null @@ -1,70 +0,0 @@ -.file-content.code { - border: none; - box-shadow: none; - margin: 0px; - padding: 0px; - table-layout: fixed; - - pre { - padding: 10px; - border: none; - border-radius: 0; - font-family: $monospace_font; - font-size: $code_font_size !important; - line-height: $code_line_height !important; - margin: 0; - overflow: auto; - overflow-y: hidden; - white-space: pre; - word-wrap: normal; - - code { - font-family: $monospace_font; - white-space: pre; - word-wrap: normal; - padding: 0; - - .line { - display: inline; - } - } - } - - .line-numbers { - padding: 10px; - text-align: right; - float: left; - - a { - font-family: $monospace_font; - display: block; - font-size: $code_font_size !important; - line-height: $code_line_height !important; - white-space: nowrap; - - i { - visibility: hidden; - @extend .pull-left; - } - - &:hover i { - visibility: visible; - } - } - } -} - -.note-text .code { - border: none; - box-shadow: none; - background: $background-color; - padding: 1em; - overflow-x: auto; - - code { - font-family: $monospace_font; - white-space: pre; - word-wrap: normal; - padding: 0; - } -} diff --git a/app/assets/stylesheets/generic/issue_box.scss b/app/assets/stylesheets/generic/issue_box.scss deleted file mode 100644 index 9558f241b7c7e96c3f93547dc4571ed38e3cb386..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/issue_box.scss +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Issue box for showing Open/Closed state: - * Used for Issue#show page, MergeRequest#show page etc - * - */ - -.issue-box { - display: inline-block; - padding: 7px 13px; - font-weight: normal; - margin-right: 5px; - - &.issue-box-closed { - background-color: $gl-danger; - color: #FFF; - } - - &.issue-box-merged { - background-color: $gl-primary; - color: #FFF; - } - - &.issue-box-open { - background-color: $gl-success; - color: #FFF; - } - - &.issue-box-expired { - background: #cea61b; - color: #FFF; - } -} diff --git a/app/assets/stylesheets/generic/jquery.scss b/app/assets/stylesheets/generic/jquery.scss deleted file mode 100644 index 871b808bad4c4aca098f8aacfae64d3160dfba1f..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/jquery.scss +++ /dev/null @@ -1,55 +0,0 @@ -.ui-widget { - font-family: $regular_font; - font-size: $font-size-base; - - &.ui-datepicker-inline { - border: 1px solid #DDD; - padding: 10px; - width: 270px; - - .ui-datepicker-header { - background: #FFF; - border-color: #DDD; - } - - .ui-datepicker-calendar td a { - padding: 5px; - text-align: center; - } - } - - &.ui-autocomplete { - border-color: #DDD; - padding: 0; - margin-top: 2px; - z-index: 1001; - - .ui-menu-item a { - padding: 4px 10px; - } - } - - .ui-state-default { - border: 1px solid #FFF; - background: #FFF; - color: #777; - } - - .ui-state-highlight { - border: 1px solid #EEE; - background: #EEE; - } - - .ui-state-active { - border: 1px solid $gl-primary; - background: $gl-primary; - color: #FFF; - } - - .ui-state-hover, - .ui-state-focus { - border: 1px solid $hover; - background: $hover; - color: #333; - } -} diff --git a/app/assets/stylesheets/generic/lists.scss b/app/assets/stylesheets/generic/lists.scss deleted file mode 100644 index 08bf6e943d2e592feb36e304b3af01ef955e3235..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/lists.scss +++ /dev/null @@ -1,128 +0,0 @@ -/** - * Well styled list - * - */ -.well-list { - margin: 0; - padding: 0; - list-style: none; - - li { - padding: 10px 15px; - min-height: 20px; - border-bottom: 1px solid #eee; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); - - &:after { - content: " "; - display: table; - clear: both; - } - - &.disabled { - color: #888; - } - - &.unstyled { - &:hover { - background: none; - } - } - - &.warning-row { - background-color: #fcf8e3; - border-color: #faebcc; - color: #8a6d3b; - } - - &.smoke { background-color: $background-color; } - - &:hover { - background: $hover; - border-bottom: 1px solid darken($hover, 10%); - } - - &:last-child { - border-bottom: none; - - &.bottom { - background: $background-color; - } - } - - .author { color: #999; } - - .list-item-name { - float: left; - position: relative; - top: 3px; - } - - p { - padding-top: 1px; - margin: 0; - color: $gray-dark; - img { - position: relative; - top: 3px; - } - } - - .well-title { - font-size: $list-font-size; - line-height: 18px; - } - - .row_title { - color: $gray-dark; - - &:hover { - color: $text-color; - text-decoration: underline; - } - } - } -} - -ol, ul { - &.styled { - li { - padding: 2px; - } - } -} - -/** light list with border-bottom between li **/ -ul.bordered-list { - margin: 5px 0px; - padding: 0px; - li { - padding: 5px 0; - border-bottom: 1px solid #EEE; - overflow: hidden; - display: block; - margin: 0px; - &:last-child { border:none } - &.active { - background: #f9f9f9; - a { font-weight: bold; } - } - - &.light { - a { color: #777; } - } - } - - &.top-list { - li:first-child { - padding-top: 0; - h4, h5 { - margin-top: 0; - } - } - } -} - -li.task-list-item { - list-style-type: none; -} diff --git a/app/assets/stylesheets/generic/markdown_area.scss b/app/assets/stylesheets/generic/markdown_area.scss deleted file mode 100644 index eb39b6bb7e99c839fe0858fbd271800101a06c50..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/markdown_area.scss +++ /dev/null @@ -1,87 +0,0 @@ -.div-dropzone-wrapper { - .div-dropzone { - position: relative; - padding: 0; - border: 0; - margin-bottom: 5px; - - .div-dropzone-focus { - border-color: #66afe9 !important; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6) !important; - outline: 0 !important; - } - - .div-dropzone-hover { - position: absolute; - top: 50%; - left: 50%; - margin-top: -0.5em; - margin-left: -0.6em; - opacity: 0; - font-size: 50px; - transition: opacity 200ms ease-in-out; - pointer-events: none; - } - - .div-dropzone-spinner { - position: absolute; - top: 100%; - left: 100%; - margin-top: -1.1em; - margin-left: -1.1em; - opacity: 0; - font-size: 30px; - transition: opacity 200ms ease-in-out; - } - - .div-dropzone-icon { - display: block; - text-align: center; - font-size: inherit; - } - - .dz-preview { - display: none; - } - } -} - -.div-dropzone-alert { - margin-top: 5px; - margin-bottom: 0; - transition: opacity 200ms ease-in-out; -} - -.md-preview-holder { - background: #FFF; - border: 1px solid #ddd; - min-height: 100px; - padding: 5px; - box-shadow: none; -} - -.new_note, -.edit_note, -.issuable-description, -.milestone-description, -.wiki-content, -.merge-request-form { - .nav-tabs { - margin-bottom: 0; - border: none; - - li a, - li.active a { - border: 1px solid #DDD; - } - } -} - -.markdown-area { - background: #FFF; - border: 1px solid #ddd; - min-height: 100px; - padding: 5px; - box-shadow: none; - width: 100%; -} diff --git a/app/assets/stylesheets/generic/mobile.scss b/app/assets/stylesheets/generic/mobile.scss deleted file mode 100644 index 71a1fc4493f4cccf0213b2a3e4697100b1586a2b..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/mobile.scss +++ /dev/null @@ -1,69 +0,0 @@ -/** Common mobile (screen XS, SM) styles **/ -@media (max-width: $screen-xs-max) { - .container .content { - margin-top: 20px; - } - - .nav.nav-tabs > li > a { - padding: 10px; - font-size: 12px; - margin-right: 3px; - - .badge { - display: none; - } - } - - .issues-filters, - .dash-projects-filters, - .check-all-holder { - display: none; - } - - .rss-btn { - display: none !important; - } - - .project-home-links { - display: none; - } -} - -@media (max-width: $screen-sm-max) { - .issues-filters { - .milestone-filter, .labels-filter { - display: none; - } - } - - .page-title { - .note_created_ago, .new-issue-link { - display: none; - } - } - - .issue_edited_ago, .note_edited_ago { - display: none; - } - - aside { - display: none; - } - - .show-aside { - display: block !important; - } -} - -.show-aside { - display: none; - position: fixed; - right: 0px; - top: 30%; - padding: 5px 15px; - background: #EEE; - font-size: 20px; - color: #777; - z-index: 100; - @include box-shadow(0 1px 2px #DDD); -} diff --git a/app/assets/stylesheets/generic/nav_sidebar.scss b/app/assets/stylesheets/generic/nav_sidebar.scss deleted file mode 100644 index 3bcb7b813330cf95bbe7e64484ac456e8f0f253c..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/nav_sidebar.scss +++ /dev/null @@ -1,193 +0,0 @@ -.page-with-sidebar { - background: $background-color; - - .sidebar-wrapper { - position: fixed; - top: 0; - left: 0; - height: 100%; - border-right: 1px solid $border-color; - } -} - -.sidebar-wrapper { - z-index: 99; - background: $background-color; -} - -.content-wrapper { - width: 100%; - padding: 15px; - background: #FFF; -} - -.nav-sidebar { - margin: 0; - list-style: none; - - &.navbar-collapse { - padding: 0px !important; - } -} - -.nav-sidebar li a .count { - float: right; - background: #eee; - padding: 0px 8px; - @include border-radius(6px); -} - -.nav-sidebar li { - &.active a { - color: $text-color; - background: #FFF !important; - font-weight: bold; - border: 1px solid #EEE; - border-right: 1px solid transparent; - border-left: 3px solid $style_color; - - &.no-highlight { - background: none !important; - border: none; - } - - i { - color: $text-color; - } - } -} - -.nav-sidebar li { - &.separate-item { - border-top: 1px solid $border-color; - padding-top: 10px; - margin-top: 10px; - } - - a { - color: $gray; - display: block; - text-decoration: none; - padding: 8px 15px; - font-size: 13px; - line-height: 20px; - padding-left: 20px; - - &:hover { - text-decoration: none; - color: $text-color; - background: $border-color; - } - - &:active, &:focus { - text-decoration: none; - } - - i { - width: 20px; - color: $gray-light; - margin-right: 23px; - } - } -} - -.sidebar-subnav { - margin-left: 0px; - padding-left: 0px; - - li { - list-style: none; - } -} - -@mixin expanded-sidebar { - padding-left: $sidebar_width; - - .sidebar-wrapper { - width: $sidebar_width; - - .nav-sidebar { - margin-top: 29px; - position: fixed; - top: 45px; - width: $sidebar_width; - } - } - - .content-wrapper { - padding: 20px; - } -} - -@mixin folded-sidebar { - padding-left: 50px; - - .sidebar-wrapper { - width: 52px; - - .nav-sidebar { - margin-top: 29px; - position: fixed; - top: 45px; - width: 52px; - - li a { - padding-left: 18px; - font-size: 14px; - padding: 8px 15px; - text-align: center; - - - & > span { - display: none; - } - } - } - - .collapse-nav a { - left: 0px; - padding: 7px 23px 3px 22px; - } - } -} - -.collapse-nav a { - position: fixed; - top: 46px; - padding: 5px 13px 5px 13px; - left: 198px; - font-size: 13px; - background: transparent; - color: black; - border-left: 1px solid $border-color; - border-bottom: 1px solid $border-color; -} - -.collapse-nav a:hover { - text-decoration: none; - background: #f2f6f7; -} - -@media (max-width: $screen-md-max) { - .page-sidebar-collapsed { - @include folded-sidebar; - } - - .page-sidebar-expanded { - @include folded-sidebar; - } - - .collapse-nav { - display: none; - } -} - -@media(min-width: $screen-md-max) { - .page-sidebar-collapsed { - @include folded-sidebar; - } - - .page-sidebar-expanded { - @include expanded-sidebar; - } -} diff --git a/app/assets/stylesheets/generic/selects.scss b/app/assets/stylesheets/generic/selects.scss deleted file mode 100644 index d8e0dc028d1371683657905daa9a54523a6f39e9..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/selects.scss +++ /dev/null @@ -1,118 +0,0 @@ -/** Select2 selectbox style override **/ -.select2-container, .select2-container.select2-drop-above { - .select2-choice { - background: #FFF; - border-color: #DDD; - height: 34px; - padding: 6px 14px; - font-size: 14px; - line-height: 1.42857143; - - @include border-radius(4px); - - .select2-arrow { - background: #FFF; - border-left: none; - padding-top: 3px; - } - } -} - -.select2-container-multi .select2-choices { - @include border-radius(4px); - border-color: #CCC; -} - -.select2-container-multi .select2-choices .select2-search-field input { - padding: 8px 14px; - font-size: 13px; - line-height: 18px; - height: auto; -} - -.select2-drop-active { - border: 1px solid #BBB !important; - margin-top: 4px; - font-size: 13px; - - &.select2-drop-above { - margin-bottom: 8px; - } - - .select2-search input { - background: #fafafa; - border-color: #DDD; - } - - .select2-results { - max-height: 350px; - .select2-highlighted { - background: $gl-primary; - } - } -} - -.select2-container { - width: 100% !important; -} - -/** Branch/tag selector **/ -.project-refs-form .select2-container { - width: 160px !important; -} - -.ajax-users-dropdown, .ajax-project-users-dropdown { - .select2-search { - padding-top: 4px; - } -} - -.ajax-users-select { - width: 400px; - - &.input-large { - width: 210px; - } - - &.input-clamp { - max-width: 100%; - } -} - -.group-result { - .group-image { - float: left; - } - .group-name { - font-weight: bold; - } - .group-path { - color: #999; - } -} - -.user-result { - .user-image { - float: left; - } - .user-name { - } - .user-username { - color: #999; - } -} - -.namespace-result { - .namespace-kind { - color: #AAA; - font-weight: normal; - } - .namespace-path { - margin-left: 10px; - font-weight: bolder; - } -} - -.ajax-users-dropdown { - min-width: 225px !important; -} diff --git a/app/assets/stylesheets/generic/tables.scss b/app/assets/stylesheets/generic/tables.scss deleted file mode 100644 index a66e45577de181764870e87bae2937d4b3dd6ccf..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/tables.scss +++ /dev/null @@ -1,20 +0,0 @@ -table { - &.table { - tr { - td, th { - padding: 8px 10px; - line-height: 20px; - vertical-align: middle; - } - th { - font-weight: normal; - font-size: 15px; - border-bottom: 1px solid $border-color !important; - } - td { - border-color: #F1F1F1 !important; - border-bottom: 1px solid; - } - } - } -} diff --git a/app/assets/stylesheets/generic/timeline.scss b/app/assets/stylesheets/generic/timeline.scss deleted file mode 100644 index 97831eb7c273a094c4b3f635aacd061c7fa5bafa..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/timeline.scss +++ /dev/null @@ -1,134 +0,0 @@ -.timeline { - list-style: none; - padding: 20px 0 20px; - position: relative; - - &:before { - top: 0; - bottom: 0; - position: absolute; - content: " "; - width: 3px; - background-color: #eeeeee; - margin-left: 29px; - } - - .timeline-entry { - position: relative; - margin-top: 5px; - margin-left: 30px; - margin-bottom: 10px; - clear: both; - - - &:target { - .timeline-entry-inner .timeline-content { - -webkit-animation:target-note 2s linear; - background: $hover; - } - } - - .timeline-entry-inner { - position: relative; - margin-left: -20px; - - &:before, &:after { - content: " "; - display: table; - } - - .timeline-icon { - margin-top: 2px; - background: #fff; - color: #737881; - float: left; - @include border-radius($avatar_radius); - @include box-shadow(0 0 0 3px #EEE); - overflow: hidden; - - .avatar { - margin: 0; - padding: 0; - } - } - - .timeline-content { - position: relative; - background: $background-color; - padding: 10px 15px; - margin-left: 60px; - - img { - max-width: 100%; - } - - &:after { - content: ''; - display: block; - position: absolute; - width: 0; - height: 0; - border-style: solid; - border-width: 9px 9px 9px 0; - border-color: transparent $background-color transparent transparent; - left: 0; - top: 10px; - margin-left: -9px; - } - } - } - } - - .system-note .timeline-entry-inner { - .timeline-icon { - background: none; - margin-left: 12px; - margin-top: 0; - @include box-shadow(none); - - span { - margin: 0 2px; - font-size: 16px; - color: #eeeeee; - } - } - - .timeline-content { - background: none; - margin-left: 45px; - padding: 0px 15px; - - &:after { border: 0; } - - .note-header { - span { font-size: 12px; } - - .avatar { - margin-right: 5px; - } - } - - .note-text { - font-size: 12px; - margin-left: 20px; - } - } - } -} - -@media (max-width: $screen-xs-max) { - .timeline { - &:before { - background: none; - } - .timeline-entry .timeline-entry-inner { - .timeline-icon { - display: none; - } - - .timeline-content { - margin-left: 0; - } - } - } -} diff --git a/app/assets/stylesheets/generic/typography.scss b/app/assets/stylesheets/generic/typography.scss deleted file mode 100644 index 80190424c1b056de0591b5ac855a78fb94ffbd84..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/typography.scss +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Headers - * - */ -.page-title { - margin-top: 0px; - line-height: 1.5; - font-weight: normal; - margin-bottom: 5px; -} - -/** CODE **/ -pre { - font-family: $monospace_font; - - &.dark { - background: #333; - color: $background-color; - } -} - -.monospace { - font-family: $monospace_font; -} - -/** - * Wiki typography - * - */ -.wiki { - @include md-typography; - - word-wrap: break-word; - - /* Link to current header. */ - h1, h2, h3, h4, h5, h6 { - position: relative; - &:hover > :last-child { - $size: 16px; - position: absolute; - right: 100%; - top: 50%; - margin-top: -$size/2; - margin-right: 0px; - padding-right: 20px; - display: inline-block; - width: $size; - height: $size; - background-image: image-url("icon-link.png"); - background-size: contain; - background-repeat: no-repeat; - } - } - - ul { - padding: 0; - margin: 0 0 9px 25px !important; - } -} - -.md { - @include md-typography; -} - -/** - * Textareas intended for GFM - * - */ -textarea.js-gfm-input { - font-family: $monospace_font; -} - -.strikethrough { - text-decoration: line-through; -} diff --git a/app/assets/stylesheets/generic/zen.scss b/app/assets/stylesheets/generic/zen.scss deleted file mode 100644 index 26afc21a6abd00e0664ce98b87432555a3cd88e2..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/generic/zen.scss +++ /dev/null @@ -1,98 +0,0 @@ -.zennable { - position: relative; - - input { - display: none; - } - - .zen-enter-link { - color: #888; - position: absolute; - top: -26px; - right: 4px; - } - - .zen-leave-link { - display: none; - color: #888; - position: absolute; - top: 10px; - right: 10px; - padding: 5px; - font-size: 36px; - - &:hover { - color: #111; - } - } - - input:checked ~ .zen-backdrop .zen-enter-link { - display: none; - } - - input:checked ~ .zen-backdrop .zen-leave-link { - display: block; - position: absolute; - top: 0; - } - - input:checked ~ .zen-backdrop { - background-color: white; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: 1031; - - textarea { - border: none; - box-shadow: none; - border-radius: 0; - color: #000; - font-size: 20px; - line-height: 26px; - padding: 30px; - display: block; - outline: none; - resize: none; - height: 100vh; - max-width: 900px; - margin: 0 auto; - } - } - - .zen-backdrop textarea::-webkit-input-placeholder { - color: white; - } - - .zen-backdrop textarea:-moz-placeholder { - color: white; - } - - .zen-backdrop textarea::-moz-placeholder { - color: white; - } - - .zen-backdrop textarea:-ms-input-placeholder { - color: white; - } - - input:checked ~ .zen-backdrop textarea::-webkit-input-placeholder { - color: #999; - } - - input:checked ~ .zen-backdrop textarea:-moz-placeholder { - color: #999; - opacity: 1; - } - - input:checked ~ .zen-backdrop textarea::-moz-placeholder { - color: #999; - opacity: 1; - } - - input:checked ~ .zen-backdrop textarea:-ms-input-placeholder { - color: #999; - } -} diff --git a/app/assets/stylesheets/highlight/dark.scss b/app/assets/stylesheets/highlight/dark.scss deleted file mode 100644 index c8cb18ec35ff9b866cd455e6add77c9c3ed14177..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/highlight/dark.scss +++ /dev/null @@ -1,88 +0,0 @@ -/* https://github.com/MozMorris/tomorrow-pygments */ -pre.code.highlight.dark, -.code.dark { - - background-color: #1d1f21; - color: #c5c8c6; - - pre.code, - .line-numbers, - .line-numbers a { - background-color: #1d1f21 !important; - color: #c5c8c6 !important; - } - - pre.code { - border-left: 1px solid #666; - } - - // highlight line via anchor - pre .hll { - background-color: #557 !important; - } - - .hll { background-color: #373b41 } - .c { color: #969896 } /* Comment */ - .err { color: #cc6666 } /* Error */ - .k { color: #b294bb } /* Keyword */ - .l { color: #de935f } /* Literal */ - .n { color: #c5c8c6 } /* Name */ - .o { color: #8abeb7 } /* Operator */ - .p { color: #c5c8c6 } /* Punctuation */ - .cm { color: #969896 } /* Comment.Multiline */ - .cp { color: #969896 } /* Comment.Preproc */ - .c1 { color: #969896 } /* Comment.Single */ - .cs { color: #969896 } /* Comment.Special */ - .gd { color: #cc6666 } /* Generic.Deleted */ - .ge { font-style: italic } /* Generic.Emph */ - .gh { color: #c5c8c6; font-weight: bold } /* Generic.Heading */ - .gi { color: #b5bd68 } /* Generic.Inserted */ - .gp { color: #969896; font-weight: bold } /* Generic.Prompt */ - .gs { font-weight: bold } /* Generic.Strong */ - .gu { color: #8abeb7; font-weight: bold } /* Generic.Subheading */ - .kc { color: #b294bb } /* Keyword.Constant */ - .kd { color: #b294bb } /* Keyword.Declaration */ - .kn { color: #8abeb7 } /* Keyword.Namespace */ - .kp { color: #b294bb } /* Keyword.Pseudo */ - .kr { color: #b294bb } /* Keyword.Reserved */ - .kt { color: #f0c674 } /* Keyword.Type */ - .ld { color: #b5bd68 } /* Literal.Date */ - .m { color: #de935f } /* Literal.Number */ - .s { color: #b5bd68 } /* Literal.String */ - .na { color: #81a2be } /* Name.Attribute */ - .nb { color: #c5c8c6 } /* Name.Builtin */ - .nc { color: #f0c674 } /* Name.Class */ - .no { color: #cc6666 } /* Name.Constant */ - .nd { color: #8abeb7 } /* Name.Decorator */ - .ni { color: #c5c8c6 } /* Name.Entity */ - .ne { color: #cc6666 } /* Name.Exception */ - .nf { color: #81a2be } /* Name.Function */ - .nl { color: #c5c8c6 } /* Name.Label */ - .nn { color: #f0c674 } /* Name.Namespace */ - .nx { color: #81a2be } /* Name.Other */ - .py { color: #c5c8c6 } /* Name.Property */ - .nt { color: #8abeb7 } /* Name.Tag */ - .nv { color: #cc6666 } /* Name.Variable */ - .ow { color: #8abeb7 } /* Operator.Word */ - .w { color: #c5c8c6 } /* Text.Whitespace */ - .mf { color: #de935f } /* Literal.Number.Float */ - .mh { color: #de935f } /* Literal.Number.Hex */ - .mi { color: #de935f } /* Literal.Number.Integer */ - .mo { color: #de935f } /* Literal.Number.Oct */ - .sb { color: #b5bd68 } /* Literal.String.Backtick */ - .sc { color: #c5c8c6 } /* Literal.String.Char */ - .sd { color: #969896 } /* Literal.String.Doc */ - .s2 { color: #b5bd68 } /* Literal.String.Double */ - .se { color: #de935f } /* Literal.String.Escape */ - .sh { color: #b5bd68 } /* Literal.String.Heredoc */ - .si { color: #de935f } /* Literal.String.Interpol */ - .sx { color: #b5bd68 } /* Literal.String.Other */ - .sr { color: #b5bd68 } /* Literal.String.Regex */ - .s1 { color: #b5bd68 } /* Literal.String.Single */ - .ss { color: #b5bd68 } /* Literal.String.Symbol */ - .bp { color: #c5c8c6 } /* Name.Builtin.Pseudo */ - .vc { color: #cc6666 } /* Name.Variable.Class */ - .vg { color: #cc6666 } /* Name.Variable.Global */ - .vi { color: #cc6666 } /* Name.Variable.Instance */ - .il { color: #de935f } /* Literal.Number.Integer.Long */ -} diff --git a/app/assets/stylesheets/highlight/monokai.scss b/app/assets/stylesheets/highlight/monokai.scss deleted file mode 100644 index 001e8b31020dda641c6e076f9a4a7d93b7c438cc..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/highlight/monokai.scss +++ /dev/null @@ -1,88 +0,0 @@ -/* https://github.com/richleland/pygments-css/blob/master/monokai.css */ -pre.code.monokai, -.code.monokai { - - background: #272822; - color: #f8f8f2; - - pre.highlight, - .line-numbers, - .line-numbers a { - background:#272822 !important; - color:#f8f8f2 !important; - } - - pre.code { - border-left: 1px solid #555; - } - - // highlight line via anchor - pre .hll { - background-color: #49483e !important; - } - - .hll { background-color: #49483e } - .c { color: #75715e } /* Comment */ - .err { color: #960050; background-color: #1e0010 } /* Error */ - .k { color: #66d9ef } /* Keyword */ - .l { color: #ae81ff } /* Literal */ - .n { color: #f8f8f2 } /* Name */ - .o { color: #f92672 } /* Operator */ - .p { color: #f8f8f2 } /* Punctuation */ - .cm { color: #75715e } /* Comment.Multiline */ - .cp { color: #75715e } /* Comment.Preproc */ - .c1 { color: #75715e } /* Comment.Single */ - .cs { color: #75715e } /* Comment.Special */ - .ge { font-style: italic } /* Generic.Emph */ - .gs { font-weight: bold } /* Generic.Strong */ - .kc { color: #66d9ef } /* Keyword.Constant */ - .kd { color: #66d9ef } /* Keyword.Declaration */ - .kn { color: #f92672 } /* Keyword.Namespace */ - .kp { color: #66d9ef } /* Keyword.Pseudo */ - .kr { color: #66d9ef } /* Keyword.Reserved */ - .kt { color: #66d9ef } /* Keyword.Type */ - .ld { color: #e6db74 } /* Literal.Date */ - .m { color: #ae81ff } /* Literal.Number */ - .s { color: #e6db74 } /* Literal.String */ - .na { color: #a6e22e } /* Name.Attribute */ - .nb { color: #f8f8f2 } /* Name.Builtin */ - .nc { color: #a6e22e } /* Name.Class */ - .no { color: #66d9ef } /* Name.Constant */ - .nd { color: #a6e22e } /* Name.Decorator */ - .ni { color: #f8f8f2 } /* Name.Entity */ - .ne { color: #a6e22e } /* Name.Exception */ - .nf { color: #a6e22e } /* Name.Function */ - .nl { color: #f8f8f2 } /* Name.Label */ - .nn { color: #f8f8f2 } /* Name.Namespace */ - .nx { color: #a6e22e } /* Name.Other */ - .py { color: #f8f8f2 } /* Name.Property */ - .nt { color: #f92672 } /* Name.Tag */ - .nv { color: #f8f8f2 } /* Name.Variable */ - .ow { color: #f92672 } /* Operator.Word */ - .w { color: #f8f8f2 } /* Text.Whitespace */ - .mf { color: #ae81ff } /* Literal.Number.Float */ - .mh { color: #ae81ff } /* Literal.Number.Hex */ - .mi { color: #ae81ff } /* Literal.Number.Integer */ - .mo { color: #ae81ff } /* Literal.Number.Oct */ - .sb { color: #e6db74 } /* Literal.String.Backtick */ - .sc { color: #e6db74 } /* Literal.String.Char */ - .sd { color: #e6db74 } /* Literal.String.Doc */ - .s2 { color: #e6db74 } /* Literal.String.Double */ - .se { color: #ae81ff } /* Literal.String.Escape */ - .sh { color: #e6db74 } /* Literal.String.Heredoc */ - .si { color: #e6db74 } /* Literal.String.Interpol */ - .sx { color: #e6db74 } /* Literal.String.Other */ - .sr { color: #e6db74 } /* Literal.String.Regex */ - .s1 { color: #e6db74 } /* Literal.String.Single */ - .ss { color: #e6db74 } /* Literal.String.Symbol */ - .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ - .vc { color: #f8f8f2 } /* Name.Variable.Class */ - .vg { color: #f8f8f2 } /* Name.Variable.Global */ - .vi { color: #f8f8f2 } /* Name.Variable.Instance */ - .il { color: #ae81ff } /* Literal.Number.Integer.Long */ - - .gh { } /* Generic Heading & Diff Header */ - .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ - .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ - .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ -} diff --git a/app/assets/stylesheets/highlight/solarized_dark.scss b/app/assets/stylesheets/highlight/solarized_dark.scss deleted file mode 100644 index f5b827e7c02e591c014a75c2b291a8293c9d3b08..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/highlight/solarized_dark.scss +++ /dev/null @@ -1,110 +0,0 @@ -/* https://gist.github.com/qguv/7936275 */ -pre.code.highlight.solarized-dark, -.code.solarized-dark { - - background-color: #002b36; - color: #93a1a1; - - pre.code, - .line-numbers, - .line-numbers a { - background-color: #002b36 !important; - color: #93a1a1 !important; - } - - pre.code { - border-left: 1px solid #113b46; - } - - // highlight line via anchor - pre .hll { - background-color: #174652 !important; - } - - /* Solarized Dark - - For use with Jekyll and Pygments - - http://ethanschoonover.com/solarized - - SOLARIZED HEX ROLE - --------- -------- ------------------------------------------ - base03 #002b36 background - base01 #586e75 comments / secondary content - base1 #93a1a1 body text / default code / primary content - orange #cb4b16 constants - red #dc322f regex, special keywords - blue #268bd2 reserved keywords - cyan #2aa198 strings, numbers - green #859900 operators, other keywords - */ - - .c { color: #586e75 } /* Comment */ - .err { color: #93a1a1 } /* Error */ - .g { color: #93a1a1 } /* Generic */ - .k { color: #859900 } /* Keyword */ - .l { color: #93a1a1 } /* Literal */ - .n { color: #93a1a1 } /* Name */ - .o { color: #859900 } /* Operator */ - .x { color: #cb4b16 } /* Other */ - .p { color: #93a1a1 } /* Punctuation */ - .cm { color: #586e75 } /* Comment.Multiline */ - .cp { color: #859900 } /* Comment.Preproc */ - .c1 { color: #586e75 } /* Comment.Single */ - .cs { color: #859900 } /* Comment.Special */ - .gd { color: #2aa198 } /* Generic.Deleted */ - .ge { color: #93a1a1; font-style: italic } /* Generic.Emph */ - .gr { color: #dc322f } /* Generic.Error */ - .gh { color: #cb4b16 } /* Generic.Heading */ - .gi { color: #859900 } /* Generic.Inserted */ - .go { color: #93a1a1 } /* Generic.Output */ - .gp { color: #93a1a1 } /* Generic.Prompt */ - .gs { color: #93a1a1; font-weight: bold } /* Generic.Strong */ - .gu { color: #cb4b16 } /* Generic.Subheading */ - .gt { color: #93a1a1 } /* Generic.Traceback */ - .kc { color: #cb4b16 } /* Keyword.Constant */ - .kd { color: #268bd2 } /* Keyword.Declaration */ - .kn { color: #859900 } /* Keyword.Namespace */ - .kp { color: #859900 } /* Keyword.Pseudo */ - .kr { color: #268bd2 } /* Keyword.Reserved */ - .kt { color: #dc322f } /* Keyword.Type */ - .ld { color: #93a1a1 } /* Literal.Date */ - .m { color: #2aa198 } /* Literal.Number */ - .s { color: #2aa198 } /* Literal.String */ - .na { color: #93a1a1 } /* Name.Attribute */ - .nb { color: #B58900 } /* Name.Builtin */ - .nc { color: #268bd2 } /* Name.Class */ - .no { color: #cb4b16 } /* Name.Constant */ - .nd { color: #268bd2 } /* Name.Decorator */ - .ni { color: #cb4b16 } /* Name.Entity */ - .ne { color: #cb4b16 } /* Name.Exception */ - .nf { color: #268bd2 } /* Name.Function */ - .nl { color: #93a1a1 } /* Name.Label */ - .nn { color: #93a1a1 } /* Name.Namespace */ - .nx { color: #93a1a1 } /* Name.Other */ - .py { color: #93a1a1 } /* Name.Property */ - .nt { color: #268bd2 } /* Name.Tag */ - .nv { color: #268bd2 } /* Name.Variable */ - .ow { color: #859900 } /* Operator.Word */ - .w { color: #93a1a1 } /* Text.Whitespace */ - .mf { color: #2aa198 } /* Literal.Number.Float */ - .mh { color: #2aa198 } /* Literal.Number.Hex */ - .mi { color: #2aa198 } /* Literal.Number.Integer */ - .mo { color: #2aa198 } /* Literal.Number.Oct */ - .sb { color: #586e75 } /* Literal.String.Backtick */ - .sc { color: #2aa198 } /* Literal.String.Char */ - .sd { color: #93a1a1 } /* Literal.String.Doc */ - .s2 { color: #2aa198 } /* Literal.String.Double */ - .se { color: #cb4b16 } /* Literal.String.Escape */ - .sh { color: #93a1a1 } /* Literal.String.Heredoc */ - .si { color: #2aa198 } /* Literal.String.Interpol */ - .sx { color: #2aa198 } /* Literal.String.Other */ - .sr { color: #dc322f } /* Literal.String.Regex */ - .s1 { color: #2aa198 } /* Literal.String.Single */ - .ss { color: #2aa198 } /* Literal.String.Symbol */ - .bp { color: #268bd2 } /* Name.Builtin.Pseudo */ - .vc { color: #268bd2 } /* Name.Variable.Class */ - .vg { color: #268bd2 } /* Name.Variable.Global */ - .vi { color: #268bd2 } /* Name.Variable.Instance */ - .il { color: #2aa198 } /* Literal.Number.Integer.Long */ -} diff --git a/app/assets/stylesheets/highlight/solarized_light.scss b/app/assets/stylesheets/highlight/solarized_light.scss deleted file mode 100644 index 6b44c00c305e3cfa618c26454496106c67ed37df..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/highlight/solarized_light.scss +++ /dev/null @@ -1,110 +0,0 @@ -/* https://gist.github.com/qguv/7936275 */ -pre.code.highlight.solarized-light, -.code.solarized-light { - - background-color: #fdf6e3; - color: #586e75; - - pre.code, - .line-numbers, - .line-numbers a { - background-color: #fdf6e3 !important; - color: #586e75 !important; - } - - pre.code { - border-left: 1px solid #c5d0d4; - } - - // highlight line via anchor - pre .hll { - background-color: #ddd8c5 !important; - } - - /* Solarized Light - - For use with Jekyll and Pygments - - http://ethanschoonover.com/solarized - - SOLARIZED HEX ROLE - --------- -------- ------------------------------------------ - base01 #586e75 body text / default code / primary content - base1 #93a1a1 comments / secondary content - base3 #fdf6e3 background - orange #cb4b16 constants - red #dc322f regex, special keywords - blue #268bd2 reserved keywords - cyan #2aa198 strings, numbers - green #859900 operators, other keywords - */ - - .c { color: #93a1a1 } /* Comment */ - .err { color: #586e75 } /* Error */ - .g { color: #586e75 } /* Generic */ - .k { color: #859900 } /* Keyword */ - .l { color: #586e75 } /* Literal */ - .n { color: #586e75 } /* Name */ - .o { color: #859900 } /* Operator */ - .x { color: #cb4b16 } /* Other */ - .p { color: #586e75 } /* Punctuation */ - .cm { color: #93a1a1 } /* Comment.Multiline */ - .cp { color: #859900 } /* Comment.Preproc */ - .c1 { color: #93a1a1 } /* Comment.Single */ - .cs { color: #859900 } /* Comment.Special */ - .gd { color: #2aa198 } /* Generic.Deleted */ - .ge { color: #586e75; font-style: italic } /* Generic.Emph */ - .gr { color: #dc322f } /* Generic.Error */ - .gh { color: #cb4b16 } /* Generic.Heading */ - .gi { color: #859900 } /* Generic.Inserted */ - .go { color: #586e75 } /* Generic.Output */ - .gp { color: #586e75 } /* Generic.Prompt */ - .gs { color: #586e75; font-weight: bold } /* Generic.Strong */ - .gu { color: #cb4b16 } /* Generic.Subheading */ - .gt { color: #586e75 } /* Generic.Traceback */ - .kc { color: #cb4b16 } /* Keyword.Constant */ - .kd { color: #268bd2 } /* Keyword.Declaration */ - .kn { color: #859900 } /* Keyword.Namespace */ - .kp { color: #859900 } /* Keyword.Pseudo */ - .kr { color: #268bd2 } /* Keyword.Reserved */ - .kt { color: #dc322f } /* Keyword.Type */ - .ld { color: #586e75 } /* Literal.Date */ - .m { color: #2aa198 } /* Literal.Number */ - .s { color: #2aa198 } /* Literal.String */ - .na { color: #586e75 } /* Name.Attribute */ - .nb { color: #B58900 } /* Name.Builtin */ - .nc { color: #268bd2 } /* Name.Class */ - .no { color: #cb4b16 } /* Name.Constant */ - .nd { color: #268bd2 } /* Name.Decorator */ - .ni { color: #cb4b16 } /* Name.Entity */ - .ne { color: #cb4b16 } /* Name.Exception */ - .nf { color: #268bd2 } /* Name.Function */ - .nl { color: #586e75 } /* Name.Label */ - .nn { color: #586e75 } /* Name.Namespace */ - .nx { color: #586e75 } /* Name.Other */ - .py { color: #586e75 } /* Name.Property */ - .nt { color: #268bd2 } /* Name.Tag */ - .nv { color: #268bd2 } /* Name.Variable */ - .ow { color: #859900 } /* Operator.Word */ - .w { color: #586e75 } /* Text.Whitespace */ - .mf { color: #2aa198 } /* Literal.Number.Float */ - .mh { color: #2aa198 } /* Literal.Number.Hex */ - .mi { color: #2aa198 } /* Literal.Number.Integer */ - .mo { color: #2aa198 } /* Literal.Number.Oct */ - .sb { color: #93a1a1 } /* Literal.String.Backtick */ - .sc { color: #2aa198 } /* Literal.String.Char */ - .sd { color: #586e75 } /* Literal.String.Doc */ - .s2 { color: #2aa198 } /* Literal.String.Double */ - .se { color: #cb4b16 } /* Literal.String.Escape */ - .sh { color: #586e75 } /* Literal.String.Heredoc */ - .si { color: #2aa198 } /* Literal.String.Interpol */ - .sx { color: #2aa198 } /* Literal.String.Other */ - .sr { color: #dc322f } /* Literal.String.Regex */ - .s1 { color: #2aa198 } /* Literal.String.Single */ - .ss { color: #2aa198 } /* Literal.String.Symbol */ - .bp { color: #268bd2 } /* Name.Builtin.Pseudo */ - .vc { color: #268bd2 } /* Name.Variable.Class */ - .vg { color: #268bd2 } /* Name.Variable.Global */ - .vi { color: #268bd2 } /* Name.Variable.Instance */ - .il { color: #2aa198 } /* Literal.Number.Integer.Long */ -} diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss deleted file mode 100644 index a52ffc971d1a4c9f47b2a8b2afc3cd70175c2d98..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/highlight/white.scss +++ /dev/null @@ -1,87 +0,0 @@ -/* https://github.com/aahan/pygments-github-style */ -pre.code.highlight.white, -.code.white { - - background-color: #fff; - color: #333; - - pre.highlight, - .line-numbers, - .line-numbers a { - background-color: #fff !important; - color: #333 !important; - } - - pre.code { - border-left: 1px solid #bbb; - } - - // highlight line via anchor - pre .hll { - background-color: #f8eec7 !important; - } - - .hll { background-color: #f8f8f8 } - .c { color: #999988; font-style: italic; } - .err { color: #a61717; background-color: #e3d2d2; } - .k { font-weight: bold; } - .o { font-weight: bold; } - .cm { color: #999988; font-style: italic; } - .cp { color: #999999; font-weight: bold; } - .c1 { color: #999988; font-style: italic; } - .cs { color: #999999; font-weight: bold; font-style: italic; } - .gd { color: #000000; background-color: #ffdddd; } - .gd .x { color: #000000; background-color: #ffaaaa; } - .ge { font-style: italic; } - .gr { color: #aa0000; } - .gh { color: #999999; } - .gi { color: #000000; background-color: #ddffdd; } - .gi .x { color: #000000; background-color: #aaffaa; } - .go { color: #888888; } - .gp { color: #555555; } - .gs { font-weight: bold; } - .gu { color: #800080; font-weight: bold; } - .gt { color: #aa0000; } - .kc { font-weight: bold; } - .kd { font-weight: bold; } - .kn { font-weight: bold; } - .kp { font-weight: bold; } - .kr { font-weight: bold; } - .kt { color: #445588; font-weight: bold; } - .m { color: #009999; } - .s { color: #dd1144; } - .n { color: #333333; } - .na { color: teal; } - .nb { color: #0086b3; } - .nc { color: #445588; font-weight: bold; } - .no { color: teal; } - .ni { color: purple; } - .ne { color: #990000; font-weight: bold; } - .nf { color: #990000; font-weight: bold; } - .nn { color: #555555; } - .nt { color: navy; } - .nv { color: teal; } - .ow { font-weight: bold; } - .w { color: #bbbbbb; } - .mf { color: #009999; } - .mh { color: #009999; } - .mi { color: #009999; } - .mo { color: #009999; } - .sb { color: #dd1144; } - .sc { color: #dd1144; } - .sd { color: #dd1144; } - .s2 { color: #dd1144; } - .se { color: #dd1144; } - .sh { color: #dd1144; } - .si { color: #dd1144; } - .sx { color: #dd1144; } - .sr { color: #009926; } - .s1 { color: #dd1144; } - .ss { color: #990073; } - .bp { color: #999999; } - .vc { color: teal; } - .vg { color: teal; } - .vi { color: teal; } - .il { color: #009999; } - .gc { color: #999; background-color: #EAF2F5; } -} diff --git a/app/assets/stylesheets/pages/admin.scss b/app/assets/stylesheets/pages/admin.scss deleted file mode 100644 index 144852e787496222c9286ffae5cbab5650967aea..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/admin.scss +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Admin area - * - */ -.admin-dashboard { - .data { - a { - h1 { - line-height: 48px; - font-size: 48px; - padding: 20px; - text-align: center; - font-weight: normal; - } - } - } - - .str-truncated { - max-width: 60%; - } -} - -.admin-filter form { - .select2-container { - width: 100% - } - - .controls { - margin-left: 130px; - } - - .form-actions { - padding-left: 130px; - background: #fff - } - - .visibility-levels { - .controls { - margin-bottom: 9px; - } - - i { - color: inherit; - } - } -} - -.broadcast-messages { - .message { - line-height: 2; - } -} - -.broadcast-message { - @extend .alert-warning; - padding: 10px; - text-align: center; -} - -.broadcast-message-preview { - @extend .broadcast-message; - margin-bottom: 20px; -} diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss deleted file mode 100644 index e7125c03993f6ae2750df72bd9df0538a25d6f66..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/commit.scss +++ /dev/null @@ -1,123 +0,0 @@ -.commit-title{ - display: block; -} - -.commit-title{ - margin-bottom: 10px; -} - -.commit-author, .commit-committer{ - display: block; - color: #999; - font-weight: normal; - font-style: italic; -} - -.commit-author strong, .commit-committer strong{ - font-weight: bold; - font-style: normal; -} - -.commit-description { - background: none; - border: none; - margin: 0; - padding: 0; - margin-top: 10px; -} - -.commit-stat-summary { - color: #666; - font-size: 14px; - font-weight: normal; - padding: 3px 0; - margin-bottom: 10px; -} - -.commit-info-row { - margin-bottom: 10px; - .avatar { - @extend .avatar-inline; - } - .commit-committer-link, - .commit-author-link { - color: #444; - font-weight: bold; - } -} - -.commit-box { - margin: 10px 0; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - padding: 20px 0; - - .commit-title { - margin: 0; - } - - .commit-description { - margin-top: 15px; - } -} - -.file-stats a { - color: $style_color; -} - -.file-stats { - .new-file { - a { - color: #090; - } - i { - color: #1BCF00; - } - } - .renamed-file { - i { - color: #FE9300; - } - } - .deleted-file { - a { - color: #B00; - } - i { - color: #EE0000; - } - } - .edit-file{ - i{ - color: #555; - } - } -} - -/* - * Commit message textarea for web editor and - * custom merge request message - */ -.commit-message-container { - background-color: $body-bg; - position: relative; - font-family: $monospace_font; - $left: 12px; - .max-width-marker { - width: 72ch; - color: rgba(0, 0, 0, 0.0); - font-family: inherit; - left: $left; - height: 100%; - border-right: 1px solid mix($input-border, white); - position: absolute; - z-index: 1; - } - > textarea { - background-color: rgba(0, 0, 0, 0.0); - font-family: inherit; - padding-left: $left; - position: relative; - z-index: 2; - } -} diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss deleted file mode 100644 index 84361e154813243dd46bf9436646ca5f7faf3306..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/commits.scss +++ /dev/null @@ -1,118 +0,0 @@ -.commits-compare-switch{ - @extend .btn; - background: image-url("switch_icon.png") no-repeat center center; - text-indent: -9999px; - float: left; - margin-right: 9px; -} - -.lists-separator { - margin: 10px 0; - border-color: #DDD; -} - -.commits-row { - ul { - margin: 0; - - li.commit { - padding: 8px 0; - } - } - - .commits-row-date { - font-size: 15px; - line-height: 20px; - margin-bottom: 5px; - } -} - -.commits-feed-holder { - float: right; - - .btn { - padding: 4px 12px; - } -} - -li.commit { - .commit-row-title { - font-size: $list-font-size; - line-height: 20px; - margin-bottom: 2px; - - .notes_count { - float: right; - margin-right: 10px; - } - - .commit_short_id { - min-width: 65px; - font-family: $monospace_font; - } - - .str-truncated { - max-width: 70%; - } - - .commit-row-message { - color: #444; - - &:hover { - text-decoration: underline; - } - } - - .text-expander { - background: #eee; - color: #555; - padding: 0 5px; - cursor: pointer; - margin-left: 4px; - &:hover { - background-color: #ddd; - } - } - } - - .commit-row-description { - font-size: 14px; - border-left: 1px solid #EEE; - padding: 10px 15px; - margin: 5px 0 10px 5px; - background: #f9f9f9; - display: none; - - pre { - border: none; - background: inherit; - padding: 0; - margin: 0; - } - } - - .commit-row-info { - color: #777; - line-height: 24px; - font-size: 13px; - - a { - color: #777; - } - - .committed_ago { - display: inline-block; - } - } - - &.inline-commit { - .commit-row-title { - font-size: 13px; - } - - .committed_ago { - float: right; - @extend .cgray; - } - } -} diff --git a/app/assets/stylesheets/pages/dashboard.scss b/app/assets/stylesheets/pages/dashboard.scss deleted file mode 100644 index af9c83e5dc8a4671f5027cb957d77985546a5379..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/dashboard.scss +++ /dev/null @@ -1,93 +0,0 @@ -.dashboard { - .side { - .panel { - .panel-heading { - background: #EEE; - border-top-left-radius: 0; - } - border-top-left-radius: 0; - } - } -} - -.dashboard-search-filter { - padding:5px; - - .search-text-input { - float:left; - @extend .col-md-2; - } - .btn { - margin-left: 5px; - float:left; - } -} - -.project-row, .group-row { - padding: 0 !important; - font-size: 14px; - line-height: 24px; - - .str-truncated { - max-width: 72%; - } - - a { - display: block; - padding: 8px 15px; - } - - .project-name, .group-name { - font-weight: 500; - } - - .arrow { - float: right; - margin: 0; - font-size: 20px; - } - - .last-activity { - float: right; - font-size: 12px; - color: #AAA; - display: block; - .date { - color: #777; - } - } -} - -.project-description { - overflow: hidden; -} - -.project-access-icon { - margin-left: 10px; - float: left; - margin-right: 15px; - margin-bottom: 15px; - - i { - color: #888; - } -} - -.dash-project-avatar { - float: left; - - .avatar { - margin-top: -8px; - margin-left: -15px; - @include border-radius(0px); - } - .identicon { - line-height: 40px; - } -} - -.dash-project-access-icon { - float: left; - margin-right: 5px; - width: 16px; -} diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss deleted file mode 100644 index af6ea58382fde2ff8ed45b35a3ef8e96ff3310e7..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/diff.scss +++ /dev/null @@ -1,358 +0,0 @@ -.diff-file { - border: 1px solid $border-color; - margin-bottom: 1em; - - .diff-header { - position: relative; - background: $background-color; - border-bottom: 1px solid $border-color; - padding: 10px 15px; - color: #555; - z-index: 10; - - > span { - font-family: $monospace_font; - word-break: break-all; - margin-right: 200px; - display: block; - - .file-mode { - margin-left: 10px; - color: #777; - } - } - - .diff-btn-group { - float: right; - position: absolute; - top: 5px; - right: 15px; - - .btn { - padding: 0px 10px; - font-size: 13px; - line-height: 28px; - } - } - - .commit-short-id { - font-family: $monospace_font; - font-size: smaller; - } - } - .diff-content { - overflow: auto; - overflow-y: hidden; - background: #FFF; - color: #333; - font-size: $code_font_size; - .old { - span.idiff { - background-color: #f8cbcb; - } - } - .new { - span.idiff { - background-color: #a6f3a6; - } - } - .unfold { - cursor: pointer; - } - - .file-mode-changed { - padding: 10px; - color: #777; - } - - table { - width: 100%; - font-family: $monospace_font; - border: none; - margin: 0px; - padding: 0px; - td { - line-height: $code_line_height; - font-size: $code_font_size; - } - } - - tr.line_holder.parallel{ - .old_line, .new_line, .diff_line { - min-width: 50px; - } - - td.line_content.parallel{ - width: 50%; - } - } - - .old_line, .new_line, .diff_line { - margin: 0px; - padding: 0px; - border: none; - background: $background-color; - color: rgba(0,0,0,0.3); - padding: 0px 5px; - border-right: 1px solid $border-color; - text-align: right; - min-width: 35px; - max-width: 50px; - width: 35px; - @include user-select(none); - a { - float: left; - width: 35px; - font-weight: normal; - color: rgba(0,0,0,0.3); - &:hover { - text-decoration: underline; - } - } - &.new { - background: #CFD; - } - &.old { - background: #FDD; - } - } - .diff_line { - padding: 0; - } - .line_holder { - &.old .old_line, - &.old .new_line { - background: #ffdddd; - border-color: #f1c0c0; - } - &.new .old_line, - &.new .new_line { - background: #dbffdb; - border-color: #c1e9c1; - } - } - .line_content { - display: block; - margin: 0px; - padding: 0px 0.5em; - border: none; - &.new { - background: #eaffea; - } - &.old { - background: #ffecec; - } - &.matched { - color: $border-color; - background: #fafafa; - } - &.parallel { - display: table-cell; - } - } - } - .image { - background: #ddd; - text-align: center; - padding: 30px; - .wrap{ - display: inline-block; - } - - .frame { - display: inline-block; - background-color: #fff; - line-height: 0; - img{ - border: 1px solid #FFF; - background: image-url('trans_bg.gif'); - max-width: 100%; - } - &.deleted { - border: 1px solid $deleted; - } - - &.added { - border: 1px solid $added; - } - } - .image-info{ - font-size: 12px; - margin: 5px 0 0 0; - color: grey; - } - - .view.swipe{ - position: relative; - - .swipe-frame{ - display: block; - margin: auto; - position: relative; - } - .swipe-wrap{ - overflow: hidden; - border-left: 1px solid #999; - position: absolute; - display: block; - top: 13px; - right: 7px; - } - .frame{ - top: 0; - right: 0; - position: absolute; - &.deleted{ - margin: 0; - display: block; - top: 13px; - right: 7px; - } - } - .swipe-bar{ - display: block; - height: 100%; - width: 15px; - z-index: 100; - position: absolute; - cursor: pointer; - &:hover{ - .top-handle{ - background-position: -15px 3px; - } - .bottom-handle{ - background-position: -15px -11px; - } - }; - .top-handle{ - display: block; - height: 14px; - width: 15px; - position: absolute; - top: 0px; - background: image-url('swipemode_sprites.gif') 0 3px no-repeat; - } - .bottom-handle{ - display: block; - height: 14px; - width: 15px; - position: absolute; - bottom: 0px; - background: image-url('swipemode_sprites.gif') 0 -11px no-repeat; - } - } - } //.view.swipe - .view.onion-skin{ - .onion-skin-frame{ - display: block; - margin: auto; - position: relative; - } - .frame.added, .frame.deleted { - position: absolute; - display: block; - top: 0px; - left: 0px; - } - .controls{ - display: block; - height: 14px; - width: 300px; - z-index: 100; - position: absolute; - bottom: 0px; - left: 50%; - margin-left: -150px; - - .drag-track{ - display: block; - position: absolute; - left: 12px; - height: 10px; - width: 276px; - background: image-url('onion_skin_sprites.gif') -4px -20px repeat-x; - } - - .dragger { - display: block; - position: absolute; - left: 0px; - top: 0px; - height: 14px; - width: 14px; - background: image-url('onion_skin_sprites.gif') 0px -34px repeat-x; - cursor: pointer; - } - - .transparent { - display: block; - position: absolute; - top: 2px; - right: 0px; - height: 10px; - width: 10px; - background: image-url('onion_skin_sprites.gif') -2px 0px no-repeat; - } - - .opaque { - display: block; - position: absolute; - top: 2px; - left: 0px; - height: 10px; - width: 10px; - background: image-url('onion_skin_sprites.gif') -2px -10px no-repeat; - } - } - } //.view.onion-skin - } - .view-modes{ - padding: 10px; - text-align: center; - background: #EEE; - - ul, li{ - list-style: none; - margin: 0; - padding: 0; - display: inline-block; - } - - li{ - color: grey; - border-left: 1px solid #c1c1c1; - padding: 0 12px 0 16px; - cursor: pointer; - &:first-child{ - border-left: none; - } - &:hover{ - text-decoration: underline; - } - &.active{ - &:hover{ - text-decoration: none; - } - cursor: default; - color: #333; - } - &.disabled{ - display: none; - } - } - } -} - -.file-content .diff-file { - margin: 0; - border: none; -} - -.diff-file .line_content { - white-space: pre; -} - -.diff-wrap-lines .line_content { - white-space: pre-wrap; -} - diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss deleted file mode 100644 index 759ba6b1c226bb0aae58f1c477e5c951755b87ba..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/editor.scss +++ /dev/null @@ -1,54 +0,0 @@ -.file-editor { - #editor{ - border: none; - @include border-radius(0); - height: 500px; - margin: 0; - padding: 0; - position: relative; - width: 100%; - } - - .cancel-btn { - color: #B94A48; - &:hover { - color: #B94A48; - } - } - .commit-button-annotation { - display: inline-block; - margin: 0; - padding: 2px; - - > * { - float: left; - } - - .message { - display: inline-block; - margin: 5px 8px 0 8px; - } - } - - .file-title { - @extend .monospace; - font-size: 14px; - padding: 5px; - } - - .editor-ref { - background: $background-color; - padding: 11px 15px; - border-right: 1px solid #CCC; - display: inline-block; - margin: -5px -5px; - margin-right: 10px; - } - - .editor-file-name { - .new-file-name { - display: inline-block; - width: 200px; - } - } -} diff --git a/app/assets/stylesheets/pages/errors.scss b/app/assets/stylesheets/pages/errors.scss deleted file mode 100644 index 32d2d7b1dbf0399882366f0fa4642e224f6994d3..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/errors.scss +++ /dev/null @@ -1,14 +0,0 @@ -.error-page { - max-width: 400px; - margin: 0 auto; - - h1, h2, h3 { - text-align: center; - } - - h1 { - font-size: 56px; - line-height: 100px; - font-weight: 300; - } -} diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss deleted file mode 100644 index d4af7506d5bbf70be3e0b79d9a38b37c704e3772..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/events.scss +++ /dev/null @@ -1,197 +0,0 @@ -/** - * Events labels - * - */ -.event_label { - &.pushed { - padding: 0 2px; - } - - &.opened { - padding: 0 2px; - } - - &.closed { - padding: 0 2px; - } - - &.merged { - padding: 0 2px; - } - - &.left, - &.joined { - padding: 0 2px; - float: none; - } -} - -/** - * Dashboard events feed - * - */ -.event-item { - &:first-child { - padding-top: 0; - } - - &.event-inline { - .avatar { - position: relative; - top: -2px; - } - } - - padding: 12px 0px; - border-bottom: 1px solid #eee; - .event-title { - max-width: 70%; - @include str-truncated(calc(100% - 174px)); - font-weight: 500; - font-size: 14px; - .author_name { - color: #333; - } - } - .event-body { - font-size: 13px; - margin-left: 35px; - margin-right: 80px; - color: #777; - - .event-note { - margin-top: 5px; - word-wrap: break-word; - - .md { - font-size: 13px; - - iframe.twitter-share-button { - vertical-align: bottom; - } - } - - pre { - border: none; - background: #f9f9f9; - border-radius: 0; - color: #777; - margin: 0 20px; - overflow: hidden; - } - - .note-image-attach { - margin-top: 4px; - margin-left: 0px; - max-width: 200px; - float: none; - } - - p:last-child { - margin-bottom: 0; - } - } - .event-note-icon { - color: #777; - float: left; - font-size: 16px; - line-height: 16px; - margin-right: 5px; - } - } - .event_icon { - position: relative; - float: right; - border: 1px solid #EEE; - padding: 5px; - @include border-radius(5px); - background: #F9F9F9; - margin-left: 10px; - top: -6px; - img { - width: 20px; - } - } - - &:last-child { border:none } - - .event_commits { - margin-top: 5px; - - li { - &.commit { - background: transparent; - padding: 3px; - padding-left: 0; - border: none; - .commit-row-title { - font-size: 12px; - } - } - &.commits-stat { - display: block; - padding: 3px; - padding-left: 0; - - &:hover { - background: none; - } - } - } - } - - .event-item-timestamp { - float: right; - color: #999; - line-height: 22px; - } -} - - -/* - * Last push widget - */ -.event-last-push { - overflow: auto; - .event-last-push-text { - @include str-truncated(100%); - padding: 5px 0; - font-size: 13px; - float:left; - margin-right: -150px; - padding-right: 150px; - line-height: 20px; - } -} - -@media (max-width: $screen-xs-max) { - .event-item { - .event-title { - white-space: normal; - overflow: visible; - max-width: 100%; - } - .avatar { - display: none; - } - - .event-body { - margin: 0; - border-left: 2px solid #DDD; - padding-left: 10px; - } - - .event-item-timestamp { - display: none; - } - } -} - -.event_filter { - li a { - font-size: 13px; - padding: 5px 10px; - background: $background-color; - margin-left: 4px; - } -} diff --git a/app/assets/stylesheets/pages/explore.scss b/app/assets/stylesheets/pages/explore.scss deleted file mode 100644 index 9b92128624c1053661040c1b2c6f2abc4d295f2c..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/explore.scss +++ /dev/null @@ -1,8 +0,0 @@ -.explore-title { - text-align: center; - - h3 { - font-weight: normal; - font-size: 30px; - } -} diff --git a/app/assets/stylesheets/pages/graph.scss b/app/assets/stylesheets/pages/graph.scss deleted file mode 100644 index c3b10d144e1b50de8e82d240beeb87e6ac6e6bbf..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/graph.scss +++ /dev/null @@ -1,37 +0,0 @@ -.project-network { - border: 1px solid $border-color; - - .controls { - color: #888; - font-size: 14px; - padding: 5px; - border-bottom: 1px solid $border-color; - background: #EEE; - } - - .network-graph { - background: #FFF; - height: 500px; - overflow-y: scroll; - overflow-x: hidden; - } -} - -.graphs { - .graph-author-commits-count { - } - - .graph-author-email { - float: right; - color: #777; - } - - .graph-additions { - color: #4a2; - } - - .graph-deletions { - color: #d12f19; - } -} - diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss deleted file mode 100644 index 2b1b747139a71d9cc080161d2c19d253934862a1..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/groups.scss +++ /dev/null @@ -1,12 +0,0 @@ -.new-group-member-holder { - margin-top: 50px; - padding-top: 20px; -} - -.member-search-form { - float: left; -} - -.milestone-row { - @include str-truncated(90%); -} diff --git a/app/assets/stylesheets/pages/header.scss b/app/assets/stylesheets/pages/header.scss deleted file mode 100644 index dde19b801f8cd639627eb5f947602192a1180c36..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/header.scss +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Application Header - * - */ -header { - &.navbar-gitlab { - z-index: 100; - margin-bottom: 0; - min-height: 40px; - border: none; - width: 100%; - - .navbar-inner { - filter: none; - - .nav > li > a { - font-size: 14px; - line-height: 32px; - padding: 6px 10px; - - &:hover, &:focus, &:active { - background: none; - } - } - - /** NAV block with links and profile **/ - .nav { - float: right; - margin-right: 0; - } - - .navbar-toggle { - color: $style_color; - margin: 0; - padding: 10px; - border-radius: 0; - - button i { font-size: 22px; } - - &.collapsed { background-color: transparent !important;} - - &:hover { - background-color: #EEE; - } - } - } - - .turbolink-spinner { - font-size: 20px; - margin-right: 10px; - } - - @media (max-width: $screen-xs-max) { - border-width: 0; - font-size: 18px; - - .title { - @include str-truncated(70%); - } - - .navbar-collapse { - margin-top: 47px; - padding-right: 0; - padding-left: 0; - } - - .navbar-nav { - margin: 5px 0; - - .visible-xs, .visable-sm { - display: table-cell !important; - } - } - - li { - display: table-cell; - width: 1%; - - a { - text-align: center; - font-size: 18px !important; - } - } - } - } - - .container { - width: 100% !important; - padding: 0px; - } - - /** - * - * Logo holder - * - */ - .app_logo { - float: left; - margin-right: 9px; - - a { - float: left; - padding: 5px 0; - height: 46px; - width: 52px; - text-align: center; - - img { - width: 36px; - height: 36px; - } - } - &:hover { - background-color: #EEE; - } - } - - /** - * - * Project / Area name - * - */ - .title { - position: relative; - float: left; - margin: 0; - margin-left: 5px; - @include header-font; - @include str-truncated(37%); - } - - .profile-pic { - padding: 0px !important; - width: 46px; - height: 46px; - margin-left: 5px; - img { - width: 46px; - height: 46px; - } - } - - /** - * - * Search box - * - */ - .search { - margin-right: 10px; - margin-left: 10px; - margin-top: 8px; - - form { - margin: 0; - padding: 0; - } - - .search-input { - background-image: image-url("icon-search.png"); - background-repeat: no-repeat; - background-position: 10px; - height: inherit; - padding: 4px 6px; - padding-left: 25px; - font-size: 13px; - @include border-radius(3px); - border: 1px solid #c6c6c6; - box-shadow: none; - @include transition(all 0.15s ease-in 0s); - } - } -} - -.search .search-input { - width: 300px; - &:focus { - width: 330px; - } -} - -@media (max-width: 1200px) { - .search .search-input { - width: 200px; - &:focus { - width: 230px; - } - } -} - -@media (max-width: $screen-xs-max) { - #nprogress .spinner { - right: 35px !important; - } -} diff --git a/app/assets/stylesheets/pages/help.scss b/app/assets/stylesheets/pages/help.scss deleted file mode 100644 index 6da7a2511a2dd0b3c0f05f4e4c10c679f1936a43..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/help.scss +++ /dev/null @@ -1,70 +0,0 @@ -.documentation-index { - h1 { - margin: 0; - } - - h2 { - font-size: 20px; - } - - li { - line-height: 24px; - color: #888; - - a { - margin-right: 3px; - } - } -} - - -.shortcut-mappings { - font-size: 12px; - color: #555; - - tbody:first-child tr:first-child { - padding-top: 0 - } - - th { - padding-top: 15px; - line-height: 1.5; - color: #333; - text-align: left - } - - td { - padding-top: 3px; - padding-bottom: 3px; - vertical-align: top; - line-height: 20px - } - - .shortcut { - padding-right: 10px; - color: #999; - text-align: right; - white-space: nowrap - } - - .key { - @extend .label; - @extend .label-inverse; - font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; - padding: 3px 5px; - } -} - -.modal-body { - position: relative; - overflow-y: auto; - padding: 15px; -} - -body.modal-open { - overflow: hidden; -} - -.modal .modal-dialog { - width: 860px; -} diff --git a/app/assets/stylesheets/pages/import.scss b/app/assets/stylesheets/pages/import.scss deleted file mode 100644 index 3df4bb84bd21edef358f8a236d09604d63a43e16..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/import.scss +++ /dev/null @@ -1,18 +0,0 @@ -i.icon-gitorious { - display: inline-block; - background-position: 0px 0px; - background-size: contain; - background-repeat: no-repeat; -} - -i.icon-gitorious-small { - background-image: image-url('gitorious-logo-blue.png'); - width: 13px; - height: 13px; -} - -i.icon-gitorious-big { - background-image: image-url('gitorious-logo-black.png'); - width: 18px; - height: 18px; -} diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss deleted file mode 100644 index a640a4e2051c489b2d8d7dc1761dc0937b6f99db..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/issuable.scss +++ /dev/null @@ -1,47 +0,0 @@ -@media (max-width: $screen-sm-max) { - .issuable-affix { - margin-top: 20px; - } -} - -@media (max-width: $screen-md-max) { - .issuable-affix { - position: static; - } -} - -@media (min-width: $screen-md-max) { - .issuable-affix { - &.affix-top { - position: static; - } - - &.affix { - position: fixed; - top: 70px; - width: 220px; - } - } -} - -.issuable-context-title { - font-size: 14px; - line-height: 1.4; - margin-bottom: 5px; - - .avatar { - margin-left: 0; - } - - label { - color: #666; - font-weight: normal; - margin-right: 4px; - } -} - -.issuable-affix .context { - font-size: 13px; - - .btn { font-size: 13px; } -} diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss deleted file mode 100644 index cd86a9be8b2753f2f472fa79e29d771eb4f1b752..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/issues.scss +++ /dev/null @@ -1,156 +0,0 @@ -.issues-list { - .issue { - padding: 10px 15px; - position: relative; - - .issue-title { - margin-bottom: 5px; - font-size: $list-font-size; - font-weight: bold; - } - - .issue-info { - color: #999; - font-size: 13px; - } - - .issue-check { - float: left; - padding-right: 8px; - margin-bottom: 10px; - min-width: 15px; - } - - .issue-labels { - display: inline-block; - } - - .issue-actions { - display: none; - position: absolute; - top: 10px; - right: 15px; - } - - &:hover { - .issue-actions { - display: block; - } - } - } -} - -.check-all-holder { - line-height: 36px; - float: left; - margin-right: 15px; -} - -.issues_content { - .title { - height: 40px; - } - - form { - margin: 0; - } -} - -.participants { - margin-bottom: 20px; -} - -.issue-search-form { - margin: 0; - height: 24px; - - .issue_search { - border: 1px solid #DDD !important; - background-color: #f4f4f4; - } -} - -.issue-show-labels { - a { - margin-right: 5px; - margin-bottom: 5px; - display: inline-block; - .color-label { - padding: 6px 10px; - } - } -} - -form.edit-issue { - margin: 0; -} - -.merge-request, -.issue { - &.today { - background: #EFE; - border-color: #CEC; - } - - &.closed { - background: #F9F9F9; - border-color: #E5E5E5; - } - - &.merged { - background: #F9F9F9; - border-color: #E5E5E5; - } -} - -@media (max-width: $screen-xs-max) { - .issue-btn-group { - width: 100%; - margin-top: 5px; - - .btn-group { - width: 100%; - - ul { - width: 100%; - text-align: center; - } - } - - .btn { - width: 100%; - margin-top: -1px; - - &:first-child:not(:last-child) { - border-radius: 4px 4px 0 0; - } - - &:not(:first-child):not(:last-child) { - border-radius: 0; - } - - &:last-child:not(:first-child) { - border-radius: 0 0 4px 4px; - } - } - } - - .issue { - &:hover .issue-actions { - display: none !important; - } - - .issue-updated-at { - display: none; - } - } -} - -h2.issue-title { - margin-top: 0; - font-weight: bold; -} - -.issue-form .select2-container { - width: 250px !important; -} diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss deleted file mode 100644 index d1590e42fcbb9bb278565491e6d3254c2d8d14be..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/labels.scss +++ /dev/null @@ -1,21 +0,0 @@ -.suggest-colors { - margin-top: 5px; - a { - @include border-radius(4px); - width: 30px; - height: 30px; - display: inline-block; - margin-right: 10px; - } -} - -.manage-labels-list { - .label { - padding: 9px; - font-size: 14px; - } -} - -.color-label { - padding: 3px 4px; -} diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss deleted file mode 100644 index 83b866c3a6466f18ffde7359d517774d80a7f373..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/login.scss +++ /dev/null @@ -1,124 +0,0 @@ -/* Login Page */ -.login-page { - .container { - max-width: 960px; - } - - .navbar-gitlab .container { - max-width: none; - } - - .brand-holder { - font-size: 18px; - line-height: 1.5; - - p { - color: #888; - } - - h1:first-child { - font-weight: normal; - margin-bottom: 30px; - } - - img { - max-width: 100%; - margin-bottom: 30px; - } - - a { - font-weight: bold; - } - } - - .login-box{ - background: #fafafa; - border-radius: 10px; - box-shadow: 0 0px 2px #CCC; - padding: 15px; - - .login-heading h3 { - font-weight: 300; - line-height: 1.5; - margin: 0 0 10px 0; - } - - .login-footer { - margin-top: 10px; - - p:last-child { - margin-bottom: 0; - } - } - - a.forgot { - float: right; - padding-top: 6px - } - - .nav .active a { - background: transparent; - } - } - - .form-control { - font-size: 14px; - padding: 10px 8px; - width: 100%; - height: auto; - - &.top { - @include border-radius(5px 5px 0 0); - margin-bottom: 0px; - } - - &.bottom { - @include border-radius(0 0 5px 5px); - border-top: 0; - margin-bottom: 20px; - } - - &.middle { - border-top: 0; - margin-bottom:0px; - @include border-radius(0); - } - - &:active, &:focus { - background-color: #FFF; - } - } - - .devise-errors { - h2 { - margin-top: 0; - font-size: 14px; - color: #a00; - } - } - - .remember-me { - margin-top: -10px; - - label { - font-weight: normal; - } - } -} - -@media (max-width: $screen-xs-max) { - .login-page { - .col-sm-5.pull-right { - float: none !important; - } - } -} - -.oauth-image-link { - margin-right: 10px; - - img { - width: 32px; - height: 32px; - } -} diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss deleted file mode 100644 index 8abd4207beb15f41f2761f07f36edb7d3871520e..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ /dev/null @@ -1,191 +0,0 @@ - - /** - * MR -> show: Automerge widget - * - */ -.automerge_widget { - form { - margin-bottom: 0; - .clearfix { - margin-bottom: 0; - } - } - - .accept-merge-holder { - .accept-action { - display: inline-block; - } - - .accept-control { - display: inline-block; - margin: 0; - margin-left: 20px; - padding: 10px 0; - line-height: 20px; - font-weight: bold; - - .remove_source_checkbox { - margin: 0; - font-weight: bold; - } - } - } -} - -@media(min-width: $screen-sm-max) { - .merge-request .merge-request-tabs{ - margin: 20px 0; - - li { - a { - padding: 15px 40px; - font-size: 14px; - } - } - } -} - -.mr_source_commit, -.mr_target_commit { - .commit { - margin: 0; - padding: 2px 0; - list-style: none; - &:hover { - background: none; - } - } -} - -.label-branch { - @include border-radius(4px); - padding: 3px 4px; - border: none; - background: $hover; - color: #333; - font-family: $monospace_font; - font-weight: normal; - overflow: hidden; - - .label-project { - @include border-radius-left(4px); - padding: 3px 4px; - background: #279; - position: relative; - left: -4px; - letter-spacing: -1px; - } -} - -.mr-list { - .merge-request { - padding: 10px 15px; - position: relative; - - .merge-request-title { - margin-bottom: 5px; - font-size: $list-font-size; - font-weight: bold; - } - - .merge-request-info { - color: #999; - font-size: 13px; - - .merge-request-labels { - display: inline-block; - } - } - } -} - -.merge-request-angle { - text-align: center; - margin: 0 auto; - font-size: 2em; - line-height: 1.1; -} - -.merge-request-form-info { - padding-top: 15px; -} - -// hide mr close link for inline diff comment form -.diff-file .close-mr-link, -.diff-file .reopen-mr-link { - display: none; -} - -.mr-state-widget { - font-size: 13px; - background: #F9F9F9; - margin-bottom: 20px; - color: #666; - border: 1px solid #EEE; - @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.09)); - - .ci_widget { - padding: 10px 15px; - font-size: 15px; - border-bottom: 1px solid #BBB; - color: #777; - background-color: $background-color; - - &.ci-success { - color: $gl-success; - border-color: $gl-success; - background-color: #F1FAF1; - } - - &.ci-pending, - &.ci-running { - color: $gl-warning; - border-color: $gl-warning; - background-color: #FAF5F1; - } - - &.ci-failed, - &.ci-canceled, - &.ci-error { - color: $gl-danger; - border-color: $gl-danger; - background-color: #FAF1F1; - } - } - - .mr-widget-body { - padding: 10px 15px; - - h4 { - font-weight: normal; - } - - p:last-child { - margin-bottom: 0; - } - } - - .mr-widget-footer { - padding: 10px 15px; - border-top: 1px solid #EEE; - } - - .ci-coverage { - float: right; - } -} - -.merge-request-show-labels { - a { - margin-right: 5px; - margin-bottom: 5px; - display: inline-block; - .color-label { - padding: 6px 10px; - } - } -} - -.merge-request-form .select2-container { - width: 250px !important; -} diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss deleted file mode 100644 index 15e3948e4027e18c716d8d3f0354216b75f41f01..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/milestone.scss +++ /dev/null @@ -1,9 +0,0 @@ -.issues-sortable-list .str-truncated { - max-width: 90%; -} - -li.milestone { - h4 { - font-weight: bold; - } -} diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss deleted file mode 100644 index a0522030785629a8b1eab56c1a879531c3a5ac78..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/note_form.scss +++ /dev/null @@ -1,175 +0,0 @@ -/** - * Note Form - */ - -.comment-btn { - @extend .btn-create; -} -.reply-btn { - @extend .btn-primary; -} -.diff-file .diff-content { - tr.line_holder:hover { - &> td.line_content { - background: $hover !important; - border-color: darken($hover, 10%) !important; - } - &> td.new_line, - &> td.old_line { - background: darken($hover, 4%) !important; - border-color: darken($hover, 10%) !important; - } - } - - tr.line_holder:hover > td .line_note_link { - opacity: 1.0; - filter: alpha(opacity=100); - } -} -.diff-file, -.discussion { - .new_note { - margin: 0; - border: none; - } -} -.new_note { - display: none; -} - -.new_note, .edit_note { - .buttons { - float: left; - margin-top: 8px; - } - .clearfix { - margin-bottom: 0; - } - - .note-preview-holder { - > p { - overflow-x: auto; - } - } - - img { - max-width: 100%; - } - - .note_text { - width: 100%; - } -} - -/* loading indicator */ -.notes-busy { - margin: 18px; -} - -.note-image-attach { - @extend .col-md-4; - @extend .thumbnail; - margin-left: 45px; - float: none; -} - -.common-note-form { - margin: 0; - background: #F9F9F9; - padding: 5px; - border: 1px solid #DDD; -} - -.note-form-actions { - background: #F9F9F9; - height: 45px; - - .note-form-option { - margin-top: 8px; - margin-left: 30px; - @extend .pull-left; - } - - .js-notify-commit-author { - float: left; - } - - .write-preview-btn { - // makes the "absolute" position for links relative to this - position: relative; - - // preview/edit buttons - > a { - position: absolute; - right: 5px; - top: 8px; - } - } -} - -.note-edit-form { - display: none; - font-size: 13px; - - .form-actions { - padding-left: 20px; - - .btn-save { - float: left; - } - - .note-form-option { - float: left; - padding: 2px 0 0 25px; - } - } -} - -.js-note-attachment-delete { - display: none; -} - -.parallel-comment { - padding: 6px; -} - -.error-alert > .alert { - margin-top: 5px; - margin-bottom: 5px; -} - -.discussion-body, -.diff-file { - .notes .note { - border-color: #ddd; - padding: 10px 15px; - } - - .discussion-reply-holder { - background: #f9f9f9; - padding: 10px 15px; - border-top: 1px solid #DDD; - } -} - -.discussion-notes-count { - font-size: 16px; -} - -.edit_note { - .markdown-area { - min-height: 140px; - } - .note-form-actions { - background: transparent; - } -} - -.comment-hints { - color: #999; - background: #FFF; - padding: 5px; - margin-top: -11px; - border: 1px solid #DDD; - font-size: 13px; -} diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss deleted file mode 100644 index facd7e193146ad66f4783f58cc9147924eb46ef2..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/notes.scss +++ /dev/null @@ -1,206 +0,0 @@ -/** - * Notes - */ - -@-webkit-keyframes targe3-note { - from { background:#fffff0; } - 50% { background:#ffffd3; } - to { background:#fffff0; } -} - -ul.notes { - display: block; - list-style: none; - margin: 0px; - padding: 0px; - - .discussion-header, - .note-header { - @extend .cgray; - padding-bottom: 15px; - - a:hover { - text-decoration: none; - } - - .avatar { - float: left; - margin-right: 10px; - } - - .discussion-last-update, - .note-last-update { - &:before { - content: "\00b7"; - } - font-size: 13px; - } - .author { - color: #333; - font-weight: bold; - &:hover { - color: $gl-link-color; - } - } - .author-username { - } - } - - .discussion { - overflow: hidden; - display: block; - position:relative; - } - - .note { - display: block; - position:relative; - .note-body { - overflow: auto; - .note-text { - overflow: auto; - word-wrap: break-word; - @include md-typography; - - hr { - margin: 10px 0; - } - } - } - .note-header { - padding-bottom: 3px; - } - - &:last-child { - border-bottom: none; - } - } -} - -// Diff code in discussion view -.discussion-body .diff-file { - .diff-header > span { - margin-right: 10px; - } - .line_content { - white-space: pre-wrap; - } -} - -.diff-file .notes_holder { - font-size: 13px; - line-height: 18px; - font-family: $regular_font; - - td { - border: 1px solid #ddd; - border-left: none; - - &.notes_line { - text-align: center; - padding: 10px 0; - background: #FFF; - } - &.notes_line2 { - text-align: center; - padding: 10px 0; - border-left: 1px solid #ddd !important; - } - &.notes_content { - background-color: #fff; - border-width: 1px 0; - padding-top: 0; - vertical-align: top; - &.parallel{ - border-width: 1px; - } - } - } -} - -/** - * Actions for Discussions/Notes - */ - -.discussion, -.note { - &.note:hover { - .note-actions { display: block; } - } - .discussion-header:hover { - .discussion-actions { display: block; } - } - - .discussion-actions, - .note-actions { - display: none; - float: right; - - [class~="fa"] { - font-size: 16px; - line-height: 16px; - vertical-align: middle; - } - - a { - @extend .cgray; - - &:hover { - &.danger { @extend .cred; } - } - } - } -} -.diff-file .note .note-actions { - right: 0; - top: 0; -} - - -/** - * Line note button on the side of diffs - */ - -.diff-file tr.line_holder { - @mixin show-add-diff-note { - filter: alpha(opacity=100); - opacity: 1.0; - } - - .add-diff-note { - margin-top: -4px; - @include border-radius(40px); - background: #FFF; - padding: 4px; - font-size: 16px; - color: $gl-link-color; - margin-left: -60px; - position: absolute; - z-index: 10; - width: 32px; - - transition: all 0.2s ease; - - // "hide" it by default - opacity: 0.0; - filter: alpha(opacity=0); - - &:hover { - width: 38px; - font-size: 20px; - background: $gl-info; - color: #FFF; - @include show-add-diff-note; - } - } - - // "show" the icon also if we just hover somewhere over the line - &:hover > td { - background: $hover !important; - - .add-diff-note { - @include show-add-diff-note; - } - } -} - diff --git a/app/assets/stylesheets/pages/notifications.scss b/app/assets/stylesheets/pages/notifications.scss deleted file mode 100644 index cc273f552227d7cca5b802939a4ef80ae2851b7b..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/notifications.scss +++ /dev/null @@ -1,22 +0,0 @@ -.global-notifications-form .level-title { - font-size: 15px; - color: #333; - font-weight: bold; -} - -.notification-icon-holder { - width: 20px; - float: left; -} - -.ns-part { - color: $gl-primary; -} - -.ns-watch { - color: $gl-success; -} - -.ns-mute { - color: $gl-danger; -} diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss deleted file mode 100644 index 65655d4bfa394dca919b8a12edc878325d0f5073..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/profile.scss +++ /dev/null @@ -1,95 +0,0 @@ -.account-page { - fieldset { - margin-bottom: 15px; - padding-bottom: 15px; - } -} - -.btn-build-token { - float: left; - padding: 6px 20px; - margin-right: 12px; -} - -.profile-avatar-form-option { - hr { - margin: 10px 0; - } -} - -/* - * Appearance settings - * - */ -.themes_opts { - label { - margin-right: 20px; - text-align: center; - - .prev { - height: 80px; - width: 160px; - margin-bottom: 10px; - @include border-radius(4px); - - &.classic { - background: #31363e; - } - - &.default { - background: #f1f1f1; - } - - &.modern { - background: #009871; - } - - &.gray { - background: #373737; - } - - &.violet { - background: #548; - } - - &.blue { - background: #2980b9; - } - } - } -} - -.code_highlight_opts { - margin-top: 10px; - - label { - margin-right: 20px; - text-align: center; - - .prev { - width: 160px; - margin-bottom: 10px; - - img { - max-width: 100%; - @include border-radius(4px); - } - } - } -} - -.oauth-buttons { - .btn-group { - margin-right: 10px; - } - - .btn { - line-height: 36px; - height: 56px; - - img { - width: 32px; - height: 32px; - } - } -} diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss deleted file mode 100644 index c005470355e1ae5995f2ad39d8803dc445f050b6..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/projects.scss +++ /dev/null @@ -1,328 +0,0 @@ -.new_project, -.edit_project { - fieldset.features { - .control-label { - font-weight: bold; - } - } -} - -.project-name-holder { - .help-inline { - vertical-align: top; - padding: 7px; - } -} - -.project-home-panel { - margin-bottom: 20px; - position: relative; - padding-left: 85px; - - &.empty-project { - border-bottom: 0px; - padding-bottom: 15px; - margin-bottom: 0px; - } - - .project-identicon-holder { - position: absolute; - left: 0; - - .avatar { - width: 70px; - height: 70px; - } - - .identicon { - font-size: 45px; - line-height: 1.6; - } - - .avatar, .identicon { - @include border-radius(4px); - box-shadow: 0 1px 2px #ddd; - } - } - - .project-home-dropdown { - margin-left: 10px; - float: right; - } - - .project-home-row { - @extend .clearfix; - margin-bottom: 15px; - - &.project-home-row-top { - margin-bottom: 15px; - } - - .project-home-desc { - font-size: 16px; - line-height: 1.3; - margin-right: 215px; - } - - .project-home-desc { - float: left; - color: $gray; - } - } - - .visibility-level-label { - color: $gray; - i { - color: inherit; - } - } - - .project-repo-buttons { - margin-top: -3px; - position: absolute; - right: 0; - width: 260px; - text-align: right; - - .btn { - font-weight: bold; - font-size: 14px; - line-height: 16px; - - .count { - padding-left: 10px; - border-left: 1px solid #ccc; - display: inline-block; - margin-left: 10px; - } - } - } -} - -.project-home-links { - padding: 10px 0px; - float: right; - a { - margin-left: 10px; - font-weight: 500; - } -} - -.git-clone-holder { - .project-home-dropdown + & { - margin-right: 45px; - } - - .form-control { - cursor: auto; - @extend .monospace; - background: #FAFAFA; - width: 100%; - } - - .input-group-addon { - background: #FAFAFA; - } -} - -.project-visibility-level-holder { - .radio { - margin-bottom: 10px; - - i { - margin: 0 3px; - font-size: 20px; - } - - .option-title { - font-weight: bold; - display: inline-block; - } - - .option-descr { - margin-left: 24px; - color: $gray; - } - } -} - -.save-project-loader { - margin-top: 50px; - margin-bottom: 50px; - color: #555; -} - -ul.nav.nav-projects-tabs { - @extend .nav-tabs; - - padding-left: 8px; - - li { - a { - padding: 6px 25px; - margin-top: 2px; - border-color: #DDD; - background-color: #EEE; - text-shadow: 0 1px 1px white; - color: #555; - } - &.active { - a { - font-weight: bold; - } - } - } -} - -.project_member_row form { - margin: 0px; -} - -.my-projects, -.public-projects { - li { - .project-info { - margin-bottom: 10px; - overflow: hidden; - } - - .access-icon { - color: #AAA; - margin-left: 10px; - i { - color: #AAA; - } - } - } -} - -.public-clone { - background: #EEE; - color: #777; - padding: 6px 10px; - margin: 1px; - font-weight: normal; -} - -.public-projects .repo-info { - color: #777; - - a { - color: #777; - } -} - -.project-side { - .btn-block { - background-image: none; - - .btn, &.btn { - white-space: normal; - text-align: left; - padding: 10px 15px; - - &.dropdown-toggle { - text-align: center; - } - - &:hover { - background-color: #eee; - border-color: #DDD; - } - } - - .count { - float: right; - font-weight: 500; - text-shadow: 0 1px #FFF; - } - - &.btn-group-justified { - .btn { - width: 100%; - } - .dropdown-toggle { - width: 30px; - padding: 10px; - } - ul { - width: 100%; - } - } - } - - .project-fork-icon { - float: left; - font-size: 26px; - margin-right: 10px; - line-height: 1.5; - } -} - -.transfer-project .select2-container { - min-width: 200px; -} - -.deploy-project-label { - margin: 1px; -} - -.vs-public { - color: $gl-primary; -} - -.vs-internal { - color: $gl-warning; -} - -.vs-private { - color: $gl-success; -} - -.breadcrumb.repo-breadcrumb { - padding: 2px 0; - background: white; - border: none; - font-size: 16px; - - > li + li:before { - padding: 0 3px; - color: #999; - } -} - -.fork-namespaces { - .thumbnail { - - &.fork-exists-thumbnail { - border-color: #EEE; - - .caption { - color: #999; - } - } - - &.fork-thumbnail { - border-color: #AAA; - - &:hover { - background-color: $hover; - } - } - - a { - text-decoration: none; - } - } -} - -table.table.protected-branches-list tr.no-border { - th, td { - border: 0; - } -} - -.project-import .btn { - float: left; - margin-right: 10px; -} diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss deleted file mode 100644 index bdaa17ac33926839777bcfdf84fe8d2c565bff1e..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/search.scss +++ /dev/null @@ -1,7 +0,0 @@ -.search-results { - .search-result-row { - border-bottom: 1px solid #EEE; - padding-bottom: 10px; - margin-bottom: 10px; - } -} diff --git a/app/assets/stylesheets/pages/snippets.scss b/app/assets/stylesheets/pages/snippets.scss deleted file mode 100644 index d79591d99156ffbfef51dec3772452777c6d53f8..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/snippets.scss +++ /dev/null @@ -1,8 +0,0 @@ -.my-snippets li:first-child { - h4 { margin-top: 0; } - padding-top: 0; -} - -.snippet-form-holder .file-holder .file-title { - padding: 2px; -} diff --git a/app/assets/stylesheets/pages/stat_graph.scss b/app/assets/stylesheets/pages/stat_graph.scss deleted file mode 100644 index b9be47e7700273cab16d2ba4c309730941fbd0b8..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/stat_graph.scss +++ /dev/null @@ -1,50 +0,0 @@ -.tint-box { - background: #f3f3f3; - position: relative; - margin-bottom: 10px; -} - -.area { - fill: #1db34f; - fill-opacity: 0.5; -} - -.axis { - fill: #aaa; - font-size: 10px; -} - -#contributors { - .contributors-list { - margin: 0 0 10px 0; - list-style: none; - padding: 0; - } - - .person { - &:nth-child(even) { - float: right; - } - float: left; - margin-top: 10px; - } - - .person .spark { - display: block; - background: #f3f3f3; - } - - .person .area-contributor { - fill: #f17f49; - } -} - -.selection rect { - fill: #333; - fill-opacity: 0.1; - stroke: #333; - stroke-width: 1px; - stroke-opacity: 0.4; - shape-rendering: crispedges; - stroke-dasharray: 3 3; -} diff --git a/app/assets/stylesheets/pages/themes.scss b/app/assets/stylesheets/pages/themes.scss deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss deleted file mode 100644 index 57f63b52aa13974c519a90807d58396e4714d923..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/tree.scss +++ /dev/null @@ -1,153 +0,0 @@ -.tree-holder { - .tree-content-holder { - float: left; - width: 100%; - } - - .tree_progress { - display: none; - margin: 20px; - &.loading { - display: block; - } - } - - .tree-table { - @extend .table; - @include border-radius(0); - - tr { - &:hover { - td { - background: $hover; - border-top: 1px solid #ADF; - border-bottom: 1px solid #ADF; - } - cursor: pointer; - } - &.selected { - td { - background: $background-color; - border-top: 1px solid #EEE; - border-bottom: 1px solid #EEE; - } - } - } - } - - .tree-item { - .tree-item-file-name { - max-width: 320px; - vertical-align: middle; - - i, a { - color: $gl-link-color; - } - - img { - position: relative; - top:-1px; - } - } - - .tree_commit { - max-width: 320px; - } - - .tree_time_ago { - min-width: 135px; - } - } - - .tree_author { - padding-right: 8px; - - .commit-author-name { - color: gray; - } - } - - .tree_commit { - color: gray; - - .tree-commit-link { - color: gray; - - &:hover { - text-decoration: underline; - } - } - } - - .blame { - img.avatar { - border: 0 none; - float: none; - margin: 0; - padding: 0; - } - td.blame-commit { - background: #f9f9f9; - min-width: 350px; - } - td.blame-numbers { - pre { - color: #AAA; - white-space: pre; - } - background: #f1f1f1; - border-left: 1px solid #DDD; - } - td.lines { - code { - font-family: $monospace_font; - } - } - } -} - -.tree-download-holder .btn { - padding: 4px 12px; -} - -.tree-ref-holder { - float: left; - margin-right: 15px; - - .select2-container .select2-choice, .select2-container.select2-drop-above .select2-choice { - padding: 4px 12px; - } -} - -.readme-holder { - .readme-file-title { - font-size: 14px; - font-weight: bold; - margin-bottom: 20px; - color: #777; - border-bottom: 1px solid #DDD; - padding: 10px 0; - } -} - -.blob-commit-info { - list-style: none; - margin: 0; - padding: 0; - margin-bottom: 10px; - - .commit { - padding: 10px 15px; - - .commit-row-title { - font-size: 13px; - - .commit-row-message { - font-weight: normal; - color: #555; - } - } - } -} - -#modal-remove-blob > .modal-dialog { width: 850px; } diff --git a/app/assets/stylesheets/pages/ui_dev_kit.scss b/app/assets/stylesheets/pages/ui_dev_kit.scss deleted file mode 100644 index 277afa1db9e5cce2fea4627a381afae859a8f6a1..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/ui_dev_kit.scss +++ /dev/null @@ -1,9 +0,0 @@ -.gitlab-ui-dev-kit { - > h2 { - font-size: 27px; - border-bottom: 1px solid #CCC; - color: #666; - margin: 30px 0; - font-weight: bold; - } -} diff --git a/app/assets/stylesheets/pages/votes.scss b/app/assets/stylesheets/pages/votes.scss deleted file mode 100644 index dc9a7d71e8ba3989d15458dcf4f72def5a01a269..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/votes.scss +++ /dev/null @@ -1,4 +0,0 @@ -.votes-inline { - display: inline-block; - margin: 0 8px; -} diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss deleted file mode 100644 index dfaeba41cf6603c3d86ca3bfeeb8ac19a9f97310..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/pages/wiki.scss +++ /dev/null @@ -1,6 +0,0 @@ -.title .edit-wiki-header { - width: 780px; - margin-left: auto; - margin-right: auto; - padding-right: 7px; -} diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss deleted file mode 100644 index 1be0551ad3be5a0f0504ae730420ff19a8e6a02a..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/print.scss +++ /dev/null @@ -1,17 +0,0 @@ -/* Generic print styles */ -header, nav, nav.main-nav, nav.navbar-collapse, nav.navbar-collapse.collapse {display: none!important;} -.profiler-results {display: none;} - -/* Styles targeted specifically at printing files */ -.tree-ref-holder, .tree-holder .breadcrumb, .blob-commit-info {display: none;} -.file-title {display: none;} -.file-holder {border: none;} - -.wiki h1, .wiki h2, .wiki h3, .wiki h4, .wiki h5, .wiki h6 {margin-top: 17px; } -.wiki h1 {font-size: 30px;} -.wiki h2 {font-size: 22px;} -.wiki h3 {font-size: 18px; font-weight: bold; } - -.sidebar-wrapper { display: none; } -.nav { display: none; } -.btn { display: none; } diff --git a/app/assets/stylesheets/themes/dark-theme.scss b/app/assets/stylesheets/themes/dark-theme.scss deleted file mode 100644 index b7b22a8724eb71eb55df740782def2e3f30aee0d..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/themes/dark-theme.scss +++ /dev/null @@ -1,63 +0,0 @@ -@mixin dark-theme($color-light, $color, $color-darker, $color-dark) { - header { - &.navbar-gitlab { - .navbar-inner { - background: $color; - - .navbar-toggle { - color: #FFF; - } - - .app_logo, .navbar-toggle { - &:hover { - background-color: $color-darker; - } - } - - .app_logo { - background-color: $color-dark; - } - - .title { - color: #FFF; - - a { - color: #FFF; - &:hover { - text-decoration: underline; - } - } - } - - .search { - .search-input { - background-color: $color-light; - background-color: rgba(255, 255, 255, 0.5); - border: 1px solid $color-light; - - &:focus { - background-color: white; - } - } - } - - .search-input::-webkit-input-placeholder { - color: #666; - } - - .nav > li > a { - color: $color-light; - - &:hover, &:focus, &:active { - background: none; - color: #FFF; - } - } - - .search-input { - border-color: $color-light; - } - } - } - } -} diff --git a/app/assets/stylesheets/themes/ui_basic.scss b/app/assets/stylesheets/themes/ui_basic.scss deleted file mode 100644 index 097d5c5b73ca41cb830de5f611d0163c1e4d0e42..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/themes/ui_basic.scss +++ /dev/null @@ -1,30 +0,0 @@ -/** - * This file represent some UI that can be changed - * during web app restyle or theme select. - * - */ -.ui_basic { - header { - &.navbar-gitlab { - .navbar-inner { - background: #F1F1F1; - border-bottom: 1px solid #DDD; - - .title { - color: #555; - - a { - color: #555; - &:hover { - text-decoration: underline; - } - } - } - - .nav > li > a { - color: $style_color; - } - } - } - } -} diff --git a/app/assets/stylesheets/themes/ui_blue.scss b/app/assets/stylesheets/themes/ui_blue.scss deleted file mode 100644 index e223058be8b79cf17fef23b0c6debc610836cea0..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/themes/ui_blue.scss +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Blue GitLab UI theme - */ -.ui_blue { - @include dark-theme(#BECDE9, #2980b9, #1970a9, #096099); -} diff --git a/app/assets/stylesheets/themes/ui_color.scss b/app/assets/stylesheets/themes/ui_color.scss deleted file mode 100644 index 7ac6903b2e422c6a66793614d847053c71c028aa..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/themes/ui_color.scss +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Violet GitLab UI theme - */ -.ui_color { - @include dark-theme(#98C, #548, #436, #325); -} diff --git a/app/assets/stylesheets/themes/ui_gray.scss b/app/assets/stylesheets/themes/ui_gray.scss deleted file mode 100644 index 9257e5f4d401193664c84ce4e9f64c13e055ba4b..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/themes/ui_gray.scss +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Gray GitLab UI theme - */ -.ui_gray { - @include dark-theme(#979797, #373737, #272727, #222222); -} diff --git a/app/assets/stylesheets/themes/ui_mars.scss b/app/assets/stylesheets/themes/ui_mars.scss deleted file mode 100644 index 4caf5843d9b048f4494eda646fc950ff91b7c981..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/themes/ui_mars.scss +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Classic GitLab UI theme - */ -.ui_mars { - @include dark-theme(#979DA7, #474D57, #373D47, #24272D); -} diff --git a/app/assets/stylesheets/themes/ui_modern.scss b/app/assets/stylesheets/themes/ui_modern.scss deleted file mode 100644 index 70449882317efef7cf129914ba4b3cbad9fa3909..0000000000000000000000000000000000000000 --- a/app/assets/stylesheets/themes/ui_modern.scss +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Modern GitLab UI theme - */ -.ui_modern { - @include dark-theme(#ADC, #019875, #018865, #017855); -} diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb deleted file mode 100644 index 6a8f20f60471fe3722bf630077b07ec5b6cf02e8..0000000000000000000000000000000000000000 --- a/app/controllers/admin/application_controller.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Provides a base class for Admin controllers to subclass -# -# Automatically sets the layout and ensures an administrator is logged in -class Admin::ApplicationController < ApplicationController - layout 'admin' - before_filter :authenticate_admin! - - def authenticate_admin! - return render_404 unless current_user.is_admin? - end -end diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb deleted file mode 100644 index b5fda196bf0e89ea4d2e5a1f5faf1273cc9bac5b..0000000000000000000000000000000000000000 --- a/app/controllers/admin/application_settings_controller.rb +++ /dev/null @@ -1,45 +0,0 @@ -class Admin::ApplicationSettingsController < Admin::ApplicationController - before_filter :set_application_setting - - def show - end - - def update - if @application_setting.update_attributes(application_setting_params) - redirect_to admin_application_settings_path, - notice: 'Application settings saved successfully' - else - render :show - end - end - - private - - def set_application_setting - @application_setting = ApplicationSetting.current - end - - def application_setting_params - restricted_levels = params[:application_setting][:restricted_visibility_levels] - if restricted_levels.nil? - params[:application_setting][:restricted_visibility_levels] = [] - else - restricted_levels.map! do |level| - level.to_i - end - end - - params.require(:application_setting).permit( - :default_projects_limit, - :default_branch_protection, - :signup_enabled, - :signin_enabled, - :gravatar_enabled, - :twitter_sharing_enabled, - :sign_in_text, - :home_page_url, - :max_attachment_size, - restricted_visibility_levels: [] - ) - end -end diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb deleted file mode 100644 index 471d24934a017a5e802018a4eca7c759bd80e0f8..0000000000000000000000000000000000000000 --- a/app/controllers/admin/applications_controller.rb +++ /dev/null @@ -1,52 +0,0 @@ -class Admin::ApplicationsController < Admin::ApplicationController - before_action :set_application, only: [:show, :edit, :update, :destroy] - - def index - @applications = Doorkeeper::Application.where("owner_id IS NULL") - end - - def show - end - - def new - @application = Doorkeeper::Application.new - end - - def edit - end - - def create - @application = Doorkeeper::Application.new(application_params) - - if @application.save - flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create]) - redirect_to admin_application_url(@application) - else - render :new - end - end - - def update - if @application.update(application_params) - redirect_to admin_application_path(@application), notice: 'Application was successfully updated.' - else - render :edit - end - end - - def destroy - @application.destroy - redirect_to admin_applications_url, notice: 'Application was successfully destroyed.' - end - - private - - def set_application - @application = Doorkeeper::Application.where("owner_id IS NULL").find(params[:id]) - end - - # Only allow a trusted parameter "white list" through. - def application_params - params[:doorkeeper_application].permit(:name, :redirect_uri) - end -end diff --git a/app/controllers/admin/background_jobs_controller.rb b/app/controllers/admin/background_jobs_controller.rb deleted file mode 100644 index 338496013a02a61954e865b003eaa9daf0377f0f..0000000000000000000000000000000000000000 --- a/app/controllers/admin/background_jobs_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Admin::BackgroundJobsController < Admin::ApplicationController - def show - ps_output, _ = Gitlab::Popen.popen(%W(ps -U #{Gitlab.config.gitlab.user} -o pid,pcpu,pmem,stat,start,command)) - @sidekiq_processes = ps_output.split("\n").grep(/sidekiq/) - end -end diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb deleted file mode 100644 index e1643bb34bf7ce3ab8a3e5f3041ce68d2b9009cb..0000000000000000000000000000000000000000 --- a/app/controllers/admin/broadcast_messages_controller.rb +++ /dev/null @@ -1,39 +0,0 @@ -class Admin::BroadcastMessagesController < Admin::ApplicationController - before_filter :broadcast_messages - - def index - @broadcast_message = BroadcastMessage.new - end - - def create - @broadcast_message = BroadcastMessage.new(broadcast_message_params) - - if @broadcast_message.save - redirect_to admin_broadcast_messages_path, notice: 'Broadcast Message was successfully created.' - else - render :index - end - end - - def destroy - BroadcastMessage.find(params[:id]).destroy - - respond_to do |format| - format.html { redirect_to :back } - format.js { render nothing: true } - end - end - - protected - - def broadcast_messages - @broadcast_messages ||= BroadcastMessage.order("starts_at DESC").page(params[:page]) - end - - def broadcast_message_params - params.require(:broadcast_message).permit( - :alert_type, :color, :ends_at, :font, - :message, :starts_at - ) - end -end diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb deleted file mode 100644 index c491e5c75501e259c300ae4586ff6464337b87e0..0000000000000000000000000000000000000000 --- a/app/controllers/admin/dashboard_controller.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Admin::DashboardController < Admin::ApplicationController - def index - @projects = Project.limit(10) - @users = User.limit(10) - @groups = Group.limit(10) - end -end diff --git a/app/controllers/admin/deploy_keys_controller.rb b/app/controllers/admin/deploy_keys_controller.rb deleted file mode 100644 index e93603bef362f304dda135f3021f725aa54e55f0..0000000000000000000000000000000000000000 --- a/app/controllers/admin/deploy_keys_controller.rb +++ /dev/null @@ -1,49 +0,0 @@ -class Admin::DeployKeysController < Admin::ApplicationController - before_filter :deploy_keys, only: [:index] - before_filter :deploy_key, only: [:show, :destroy] - - def index - - end - - def show - - end - - def new - @deploy_key = deploy_keys.new - end - - def create - @deploy_key = deploy_keys.new(deploy_key_params) - - if @deploy_key.save - redirect_to admin_deploy_keys_path - else - render "new" - end - end - - def destroy - deploy_key.destroy - - respond_to do |format| - format.html { redirect_to admin_deploy_keys_path } - format.json { head :ok } - end - end - - protected - - def deploy_key - @deploy_key ||= deploy_keys.find(params[:id]) - end - - def deploy_keys - @deploy_keys ||= DeployKey.are_public - end - - def deploy_key_params - params.require(:deploy_key).permit(:key, :title) - end -end diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb deleted file mode 100644 index 22d045fc388a07332a29c155da38a6e5b401f881..0000000000000000000000000000000000000000 --- a/app/controllers/admin/groups_controller.rb +++ /dev/null @@ -1,64 +0,0 @@ -class Admin::GroupsController < Admin::ApplicationController - before_filter :group, only: [:edit, :show, :update, :destroy, :project_update, :members_update] - - def index - @groups = Group.all - @groups = @groups.sort(@sort = params[:sort]) - @groups = @groups.search(params[:name]) if params[:name].present? - @groups = @groups.page(params[:page]).per(PER_PAGE) - end - - def show - @members = @group.members.order("access_level DESC").page(params[:members_page]).per(PER_PAGE) - @projects = @group.projects.page(params[:projects_page]).per(PER_PAGE) - end - - def new - @group = Group.new - end - - def edit - end - - def create - @group = Group.new(group_params) - @group.name = @group.path.dup unless @group.name - - if @group.save - @group.add_owner(current_user) - redirect_to [:admin, @group], notice: 'Group was successfully created.' - else - render "new" - end - end - - def update - if @group.update_attributes(group_params) - redirect_to [:admin, @group], notice: 'Group was successfully updated.' - else - render "edit" - end - end - - def members_update - @group.add_users(params[:user_ids].split(','), params[:access_level], current_user) - - redirect_to [:admin, @group], notice: 'Users were successfully added.' - end - - def destroy - @group.destroy - - redirect_to admin_groups_path, notice: 'Group was successfully deleted.' - end - - private - - def group - @group = Group.find_by(path: params[:id]) - end - - def group_params - params.require(:group).permit(:name, :description, :path, :avatar) - end -end diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb deleted file mode 100644 index 0a463239d7496d7e27f8d7b1eb998ad1ab95df4f..0000000000000000000000000000000000000000 --- a/app/controllers/admin/hooks_controller.rb +++ /dev/null @@ -1,44 +0,0 @@ -class Admin::HooksController < Admin::ApplicationController - def index - @hooks = SystemHook.all - @hook = SystemHook.new - end - - def create - @hook = SystemHook.new(hook_params) - - if @hook.save - redirect_to admin_hooks_path, notice: 'Hook was successfully created.' - else - @hooks = SystemHook.all - render :index - end - end - - def destroy - @hook = SystemHook.find(params[:id]) - @hook.destroy - - redirect_to admin_hooks_path - end - - - def test - @hook = SystemHook.find(params[:hook_id]) - data = { - event_name: "project_create", - name: "Ruby", - path: "ruby", - project_id: 1, - owner_name: "Someone", - owner_email: "example@gitlabhq.com" - } - @hook.execute(data) - - redirect_to :back - end - - def hook_params - params.require(:hook).permit(:url) - end -end diff --git a/app/controllers/admin/keys_controller.rb b/app/controllers/admin/keys_controller.rb deleted file mode 100644 index 21111bb44f5aa9cb5c3f3e0f8b7516a7e78272a7..0000000000000000000000000000000000000000 --- a/app/controllers/admin/keys_controller.rb +++ /dev/null @@ -1,34 +0,0 @@ -class Admin::KeysController < Admin::ApplicationController - before_filter :user, only: [:show, :destroy] - - def show - @key = user.keys.find(params[:id]) - - respond_to do |format| - format.html - format.js { render nothing: true } - end - end - - def destroy - key = user.keys.find(params[:id]) - - respond_to do |format| - if key.destroy - format.html { redirect_to [:admin, user], notice: 'User key was successfully removed.' } - else - format.html { redirect_to [:admin, user], alert: 'Failed to remove user key.' } - end - end - end - - protected - - def user - @user ||= User.find_by!(username: params[:user_id]) - end - - def key_params - params.require(:user_id, :id) - end -end diff --git a/app/controllers/admin/logs_controller.rb b/app/controllers/admin/logs_controller.rb deleted file mode 100644 index b999018dde469e3f32187b94551077c56a56a174..0000000000000000000000000000000000000000 --- a/app/controllers/admin/logs_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class Admin::LogsController < Admin::ApplicationController -end diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb deleted file mode 100644 index 5176a8399ae63b74ead7232cc94b6dca7d6df449..0000000000000000000000000000000000000000 --- a/app/controllers/admin/projects_controller.rb +++ /dev/null @@ -1,44 +0,0 @@ -class Admin::ProjectsController < Admin::ApplicationController - before_filter :project, only: [:show, :transfer] - before_filter :group, only: [:show, :transfer] - before_filter :repository, only: [:show, :transfer] - - def index - @projects = Project.all - @projects = @projects.where(namespace_id: params[:namespace_id]) if params[:namespace_id].present? - @projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present? - @projects = @projects.with_push if params[:with_push].present? - @projects = @projects.abandoned if params[:abandoned].present? - @projects = @projects.search(params[:name]) if params[:name].present? - @projects = @projects.sort(@sort = params[:sort]) - @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(PER_PAGE) - end - - def show - if @group - @group_members = @group.members.order("access_level DESC").page(params[:group_members_page]).per(PER_PAGE) - end - - @project_members = @project.project_members.page(params[:project_members_page]).per(PER_PAGE) - end - - def transfer - ::Projects::TransferService.new(@project, current_user, params.dup).execute - - @project.reload - redirect_to admin_namespace_project_path(@project.namespace, @project) - end - - protected - - def project - @project = Project.find_with_namespace( - [params[:namespace_id], '/', params[:id]].join('') - ) - @project || render_404 - end - - def group - @group ||= @project.group - end -end diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb deleted file mode 100644 index 76a938c5fe4fd8587c4a75659946dad255edfe2b..0000000000000000000000000000000000000000 --- a/app/controllers/admin/services_controller.rb +++ /dev/null @@ -1,54 +0,0 @@ -class Admin::ServicesController < Admin::ApplicationController - before_filter :service, only: [:edit, :update] - - def index - @services = services_templates - end - - def edit - unless service.present? - redirect_to admin_application_settings_services_path, - alert: "Service is unknown or it doesn't exist" - end - end - - def update - if service.update_attributes(application_services_params[:service]) - redirect_to admin_application_settings_services_path, - notice: 'Application settings saved successfully' - else - render :edit - end - end - - private - - def services_templates - templates = [] - - Service.available_services_names.each do |service_name| - service_template = service_name.concat("_service").camelize.constantize - templates << service_template.where(template: true).first_or_create - end - - templates - end - - def service - @service ||= Service.where(id: params[:id], template: true).first - end - - def application_services_params - params.permit(:id, - service: [ - :title, :token, :type, :active, :api_key, :subdomain, - :room, :recipients, :project_url, :webhook, - :user_key, :device, :priority, :sound, :bamboo_url, :username, :password, - :build_key, :server, :teamcity_url, :build_type, - :description, :issues_url, :new_issue_url, :restrict_to_branch, - :send_from_committer_email, :disable_diffs, - :push_events, :tag_push_events, :note_events, :issues_events, - :merge_requests_events - ]) - end -end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb deleted file mode 100644 index b4c011f213c1bd3507f5940ed2f146301322f104..0000000000000000000000000000000000000000 --- a/app/controllers/admin/users_controller.rb +++ /dev/null @@ -1,128 +0,0 @@ -class Admin::UsersController < Admin::ApplicationController - before_filter :user, only: [:show, :edit, :update, :destroy] - - def index - @users = User.order_name_asc.filter(params[:filter]) - @users = @users.search(params[:name]) if params[:name].present? - @users = @users.sort(@sort = params[:sort]) - @users = @users.page(params[:page]) - end - - def show - @personal_projects = user.personal_projects - @joined_projects = user.projects.joined(@user) - @keys = user.keys - end - - def new - @user = User.new - end - - def edit - user - end - - def block - if user.block - redirect_to :back, notice: "Successfully blocked" - else - redirect_to :back, alert: "Error occurred. User was not blocked" - end - end - - def unblock - if user.activate - redirect_to :back, notice: "Successfully unblocked" - else - redirect_to :back, alert: "Error occurred. User was not unblocked" - end - end - - def create - opts = { - force_random_password: true, - password_expires_at: nil - } - - @user = User.new(user_params.merge(opts)) - @user.created_by_id = current_user.id - @user.generate_password - @user.generate_reset_token - @user.skip_confirmation! - - respond_to do |format| - if @user.save - format.html { redirect_to [:admin, @user], notice: 'User was successfully created.' } - format.json { render json: @user, status: :created, location: @user } - else - format.html { render "new" } - format.json { render json: @user.errors, status: :unprocessable_entity } - end - end - end - - def update - user_params_with_pass = user_params.dup - - if params[:user][:password].present? - user_params_with_pass.merge!( - password: params[:user][:password], - password_confirmation: params[:user][:password_confirmation], - ) - end - - respond_to do |format| - user.skip_reconfirmation! - if user.update_attributes(user_params_with_pass) - format.html { redirect_to [:admin, user], notice: 'User was successfully updated.' } - format.json { head :ok } - else - # restore username to keep form action url. - user.username = params[:id] - format.html { render "edit" } - format.json { render json: user.errors, status: :unprocessable_entity } - end - end - end - - def destroy - # 1. Remove groups where user is the only owner - user.solo_owned_groups.map(&:destroy) - - # 2. Remove user with all authored content including personal projects - user.destroy - - respond_to do |format| - format.html { redirect_to admin_users_path } - format.json { head :ok } - end - end - - def remove_email - email = user.emails.find(params[:email_id]) - email.destroy - - user.set_notification_email - user.save if user.notification_email_changed? - - respond_to do |format| - format.html { redirect_to :back, notice: "Successfully removed email." } - format.js { render nothing: true } - end - end - - protected - - def user - @user ||= User.find_by!(username: params[:id]) - end - - def user_params - params.require(:user).permit( - :email, :remember_me, :bio, :name, :username, - :skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password, - :extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key, :hide_no_password, - :projects_limit, :can_create_group, :admin, :key_id - ) - end -end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb deleted file mode 100644 index 920a981e7c9bc3501f241fc6cdc262128378737e..0000000000000000000000000000000000000000 --- a/app/controllers/application_controller.rb +++ /dev/null @@ -1,345 +0,0 @@ -require 'gon' - -class ApplicationController < ActionController::Base - include Gitlab::CurrentSettings - include GitlabRoutingHelper - - PER_PAGE = 20 - - before_filter :authenticate_user_from_token! - before_filter :authenticate_user! - before_filter :reject_blocked! - before_filter :check_password_expiration - before_filter :ldap_security_check - before_filter :default_headers - before_filter :add_gon_variables - before_filter :configure_permitted_parameters, if: :devise_controller? - before_filter :require_email, unless: :devise_controller? - - protect_from_forgery with: :exception - - helper_method :abilities, :can?, :current_application_settings - helper_method :github_import_enabled?, :gitlab_import_enabled?, :bitbucket_import_enabled? - - rescue_from Encoding::CompatibilityError do |exception| - log_exception(exception) - render "errors/encoding", layout: "errors", status: 500 - end - - rescue_from ActiveRecord::RecordNotFound do |exception| - log_exception(exception) - render "errors/not_found", layout: "errors", status: 404 - end - - protected - - # From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example - # https://gist.github.com/josevalim/fb706b1e933ef01e4fb6 - def authenticate_user_from_token! - user_token = if params[:authenticity_token].presence - params[:authenticity_token].presence - elsif params[:private_token].presence - params[:private_token].presence - end - user = user_token && User.find_by_authentication_token(user_token.to_s) - - if user - # Notice we are passing store false, so the user is not - # actually stored in the session and a token is needed - # for every request. If you want the token to work as a - # sign in token, you can simply remove store: false. - sign_in user, store: false - end - end - - def authenticate_user!(*args) - # If user is not signed-in and tries to access root_path - redirect him to landing page - if current_application_settings.home_page_url.present? - if current_user.nil? && controller_name == 'dashboard' && action_name == 'show' - redirect_to current_application_settings.home_page_url and return - end - end - - super(*args) - end - - def log_exception(exception) - application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace - application_trace.map!{ |t| " #{t}\n" } - logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}" - end - - def reject_blocked! - if current_user && current_user.blocked? - sign_out current_user - flash[:alert] = "Your account is blocked. Retry when an admin has unblocked it." - redirect_to new_user_session_path - end - end - - def after_sign_in_path_for(resource) - if resource.is_a?(User) && resource.respond_to?(:blocked?) && resource.blocked? - sign_out resource - flash[:alert] = "Your account is blocked. Retry when an admin has unblocked it." - new_user_session_path - else - stored_location_for(:redirect) || stored_location_for(resource) || root_path - end - end - - def abilities - Ability.abilities - end - - def can?(object, action, subject) - abilities.allowed?(object, action, subject) - end - - def project - unless @project - namespace = params[:namespace_id] - id = params[:project_id] || params[:id] - - # Redirect from - # localhost/group/project.git - # to - # localhost/group/project - # - if id =~ /\.git\Z/ - redirect_to request.original_url.gsub(/\.git\Z/, '') and return - end - - @project = Project.find_with_namespace("#{namespace}/#{id}") - - if @project and can?(current_user, :read_project, @project) - @project - elsif current_user.nil? - @project = nil - authenticate_user! - else - @project = nil - render_404 and return - end - end - @project - end - - def repository - @repository ||= project.repository - rescue Grit::NoSuchPathError => e - log_exception(e) - nil - end - - def authorize_project!(action) - return access_denied! unless can?(current_user, action, project) - end - - def authorize_labels! - # Labels should be accessible for issues and/or merge requests - authorize_read_issue! || authorize_read_merge_request! - end - - def access_denied! - render "errors/access_denied", layout: "errors", status: 404 - end - - def not_found! - render "errors/not_found", layout: "errors", status: 404 - end - - def git_not_found! - render "errors/git_not_found", layout: "errors", status: 404 - end - - def method_missing(method_sym, *arguments, &block) - if method_sym.to_s =~ /\Aauthorize_(.*)!\z/ - authorize_project!($1.to_sym) - else - super - end - end - - def render_403 - head :forbidden - end - - def render_404 - render file: Rails.root.join("public", "404"), layout: false, status: "404" - end - - def require_non_empty_project - redirect_to @project if @project.empty_repo? - end - - def no_cache_headers - response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate" - response.headers["Pragma"] = "no-cache" - response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT" - end - - def default_url_options - if !Rails.env.test? - port = Gitlab.config.gitlab.port unless Gitlab.config.gitlab_on_standard_port? - { host: Gitlab.config.gitlab.host, - protocol: Gitlab.config.gitlab.protocol, - port: port, - script_name: Gitlab.config.gitlab.relative_url_root } - else - super - end - end - - def default_headers - headers['X-Frame-Options'] = 'DENY' - headers['X-XSS-Protection'] = '1; mode=block' - headers['X-UA-Compatible'] = 'IE=edge' - headers['X-Content-Type-Options'] = 'nosniff' - headers['Strict-Transport-Security'] = 'max-age=31536000' if Gitlab.config.gitlab.https - end - - def add_gon_variables - gon.default_issues_tracker = Project.new.default_issue_tracker.to_param - gon.api_version = API::API.version - gon.relative_url_root = Gitlab.config.gitlab.relative_url_root - gon.default_avatar_url = URI::join(Gitlab.config.gitlab.url, ActionController::Base.helpers.image_path('no_avatar.png')).to_s - gon.max_file_size = current_application_settings.max_attachment_size; - - if current_user - gon.current_user_id = current_user.id - gon.api_token = current_user.private_token - end - end - - def check_password_expiration - if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now && !current_user.ldap_user? - redirect_to new_profile_password_path and return - end - end - - def ldap_security_check - if current_user && current_user.requires_ldap_check? - unless Gitlab::LDAP::Access.allowed?(current_user) - sign_out current_user - flash[:alert] = "Access denied for your LDAP account." - redirect_to new_user_session_path - end - end - end - - def event_filter - filters = cookies['event_filter'].split(',') if cookies['event_filter'].present? - @event_filter ||= EventFilter.new(filters) - end - - def gitlab_ldap_access(&block) - Gitlab::LDAP::Access.open { |access| block.call(access) } - end - - # JSON for infinite scroll via Pager object - def pager_json(partial, count) - html = render_to_string( - partial, - layout: false, - formats: [:html] - ) - - render json: { - html: html, - count: count - } - end - - def view_to_html_string(partial) - render_to_string( - partial, - layout: false, - formats: [:html] - ) - end - - def configure_permitted_parameters - devise_parameter_sanitizer.sanitize(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me) } - end - - def hexdigest(string) - Digest::SHA1.hexdigest string - end - - def require_email - if current_user && current_user.temp_oauth_email? - redirect_to profile_path, notice: 'Please complete your profile with email address' and return - end - end - - def set_filters_params - params[:sort] ||= 'created_desc' - params[:scope] = 'all' if params[:scope].blank? - params[:state] = 'opened' if params[:state].blank? - - @filter_params = params.dup - - if @project - @filter_params[:project_id] = @project.id - elsif @group - @filter_params[:group_id] = @group.id - else - # TODO: this filter ignore issues/mr created in public or - # internal repos where you are not a member. Enable this filter - # or improve current implementation to filter only issues you - # created or assigned or mentioned - #@filter_params[:authorized_only] = true - end - - @filter_params - end - - def set_filter_values(collection) - assignee_id = @filter_params[:assignee_id] - author_id = @filter_params[:author_id] - milestone_id = @filter_params[:milestone_id] - - @sort = @filter_params[:sort] - @assignees = User.where(id: collection.pluck(:assignee_id)) - @authors = User.where(id: collection.pluck(:author_id)) - @milestones = Milestone.where(id: collection.pluck(:milestone_id)) - - if assignee_id.present? && !assignee_id.to_i.zero? - @assignee = @assignees.find_by(id: assignee_id) - end - - if author_id.present? && !author_id.to_i.zero? - @author = @authors.find_by(id: author_id) - end - - if milestone_id.present? && !milestone_id.to_i.zero? - @milestone = @milestones.find_by(id: milestone_id) - end - end - - def get_issues_collection - set_filters_params - issues = IssuesFinder.new.execute(current_user, @filter_params) - set_filter_values(issues) - issues - end - - def get_merge_requests_collection - set_filters_params - merge_requests = MergeRequestsFinder.new.execute(current_user, @filter_params) - set_filter_values(merge_requests) - merge_requests - end - - def github_import_enabled? - OauthHelper.enabled_oauth_providers.include?(:github) - end - - def gitlab_import_enabled? - OauthHelper.enabled_oauth_providers.include?(:gitlab) - end - - def bitbucket_import_enabled? - OauthHelper.enabled_oauth_providers.include?(:bitbucket) && Gitlab::BitbucketImport.public_key.present? - end -end diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb deleted file mode 100644 index 11af9895261f1a683df092e4f03d9dad02a6e0c5..0000000000000000000000000000000000000000 --- a/app/controllers/autocomplete_controller.rb +++ /dev/null @@ -1,30 +0,0 @@ -class AutocompleteController < ApplicationController - def users - @users = - if params[:project_id].present? - project = Project.find(params[:project_id]) - - if can?(current_user, :read_project, project) - project.team.users - end - elsif params[:group_id] - group = Group.find(params[:group_id]) - - if can?(current_user, :read_group, group) - group.users - end - else - User.all - end - - @users = @users.search(params[:search]) if params[:search].present? - @users = @users.active - @users = @users.page(params[:page]).per(PER_PAGE) - render json: @users, only: [:name, :username, :id], methods: [:avatar_url] - end - - def user - @user = User.find(params[:id]) - render json: @user, only: [:name, :username, :id], methods: [:avatar_url] - end -end diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb deleted file mode 100644 index af1faca93f6cb969fe7a7206df92d6f2dc53075b..0000000000000000000000000000000000000000 --- a/app/controllers/confirmations_controller.rb +++ /dev/null @@ -1,17 +0,0 @@ -class ConfirmationsController < Devise::ConfirmationsController - - protected - - def after_confirmation_path_for(resource_name, resource) - if signed_in?(resource_name) - after_sign_in_path_for(resource) - else - sign_in(resource) - if signed_in?(resource_name) - after_sign_in_path_for(resource) - else - new_session_path(resource_name) - end - end - end -end diff --git a/app/controllers/dashboard/groups_controller.rb b/app/controllers/dashboard/groups_controller.rb deleted file mode 100644 index ed14f4e1f3baa9689c8d000381dc67179560a7f3..0000000000000000000000000000000000000000 --- a/app/controllers/dashboard/groups_controller.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Dashboard::GroupsController < ApplicationController - def index - @group_members = current_user.group_members.page(params[:page]).per(PER_PAGE) - end -end diff --git a/app/controllers/dashboard/milestones_controller.rb b/app/controllers/dashboard/milestones_controller.rb deleted file mode 100644 index cb51792df16f223fce050bcaf3ff170a62520cb6..0000000000000000000000000000000000000000 --- a/app/controllers/dashboard/milestones_controller.rb +++ /dev/null @@ -1,34 +0,0 @@ -class Dashboard::MilestonesController < ApplicationController - before_filter :load_projects - - def index - project_milestones = case params[:state] - when 'all'; state - when 'closed'; state('closed') - else state('active') - end - @dashboard_milestones = Milestones::GroupService.new(project_milestones).execute - @dashboard_milestones = Kaminari.paginate_array(@dashboard_milestones).page(params[:page]).per(PER_PAGE) - end - - def show - project_milestones = Milestone.where(project_id: @projects).order("due_date ASC") - @dashboard_milestone = Milestones::GroupService.new(project_milestones).milestone(title) - end - - private - - def load_projects - @projects = current_user.authorized_projects.sorted_by_activity.non_archived - end - - def title - params[:title] - end - - def state(state = nil) - conditions = { project_id: @projects } - conditions.reverse_merge!(state: state) if state - Milestone.where(conditions).order("title ASC") - end -end diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb deleted file mode 100644 index 56e6fcc41ca1445c54150b4f9653968d5091c166..0000000000000000000000000000000000000000 --- a/app/controllers/dashboard/projects_controller.rb +++ /dev/null @@ -1,27 +0,0 @@ -class Dashboard::ProjectsController < ApplicationController - before_filter :event_filter - - def starred - @projects = current_user.starred_projects - @projects = @projects.includes(:namespace, :forked_from_project, :tags) - @projects = @projects.sort(@sort = params[:sort]) - @groups = [] - - respond_to do |format| - format.html - - format.json do - load_events - pager_json("events/_events", @events.count) - end - end - end - - private - - def load_events - @events = Event.in_projects(@projects.pluck(:id)) - @events = @event_filter.apply_filter(@events).with_associations - @events = @events.limit(20).offset(params[:offset] || 0) - end -end diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb deleted file mode 100644 index 9bd853ed5c70ef751c6cf40b6144ed3c77937e59..0000000000000000000000000000000000000000 --- a/app/controllers/dashboard_controller.rb +++ /dev/null @@ -1,54 +0,0 @@ -class DashboardController < ApplicationController - respond_to :html - - before_filter :load_projects, except: [:projects] - before_filter :event_filter, only: :show - - def show - @projects = @projects.includes(:namespace) - @last_push = current_user.recent_push - - respond_to do |format| - format.html - - format.json do - load_events - pager_json("events/_events", @events.count) - end - - format.atom do - load_events - render layout: false - end - end - end - - def merge_requests - @merge_requests = get_merge_requests_collection - @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) - @merge_requests = @merge_requests.preload(:author, :target_project) - end - - def issues - @issues = get_issues_collection - @issues = @issues.page(params[:page]).per(PER_PAGE) - @issues = @issues.preload(:author, :project) - - respond_to do |format| - format.html - format.atom { render layout: false } - end - end - - protected - - def load_projects - @projects = current_user.authorized_projects.sorted_by_activity.non_archived - end - - def load_events - @events = Event.in_projects(current_user.authorized_projects.pluck(:id)) - @events = @event_filter.apply_filter(@events).with_associations - @events = @events.limit(20).offset(params[:offset] || 0) - end -end diff --git a/app/controllers/explore/groups_controller.rb b/app/controllers/explore/groups_controller.rb deleted file mode 100644 index c51a4a211a6210688350602240c8f6f5c5a744d1..0000000000000000000000000000000000000000 --- a/app/controllers/explore/groups_controller.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Explore::GroupsController < ApplicationController - skip_before_filter :authenticate_user!, - :reject_blocked, :set_current_user_for_observers - - layout "explore" - - def index - @groups = GroupsFinder.new.execute(current_user) - @groups = @groups.search(params[:search]) if params[:search].present? - @groups = @groups.sort(@sort = params[:sort]) - @groups = @groups.page(params[:page]).per(PER_PAGE) - end -end diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb deleted file mode 100644 index b295f295bb10fbf0e1798a17af79500c4279f7ec..0000000000000000000000000000000000000000 --- a/app/controllers/explore/projects_controller.rb +++ /dev/null @@ -1,27 +0,0 @@ -class Explore::ProjectsController < ApplicationController - skip_before_filter :authenticate_user!, - :reject_blocked - - layout 'explore' - - def index - @projects = ProjectsFinder.new.execute(current_user) - @tags = @projects.tags_on(:tags) - @projects = @projects.tagged_with(params[:tag]) if params[:tag].present? - @projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present? - @projects = @projects.search(params[:search]) if params[:search].present? - @projects = @projects.sort(@sort = params[:sort]) - @projects = @projects.includes(:namespace).page(params[:page]).per(PER_PAGE) - end - - def trending - @trending_projects = TrendingProjectsFinder.new.execute(current_user) - @trending_projects = @trending_projects.page(params[:page]).per(PER_PAGE) - end - - def starred - @starred_projects = ProjectsFinder.new.execute(current_user) - @starred_projects = @starred_projects.reorder('star_count DESC') - @starred_projects = @starred_projects.page(params[:page]).per(PER_PAGE) - end -end diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb deleted file mode 100644 index 469a6813ee22a5e80f262705b3ed7208b3964c4c..0000000000000000000000000000000000000000 --- a/app/controllers/groups/application_controller.rb +++ /dev/null @@ -1,28 +0,0 @@ -class Groups::ApplicationController < ApplicationController - - private - - def authorize_read_group! - unless @group and can?(current_user, :read_group, @group) - if current_user.nil? - return authenticate_user! - else - return render_404 - end - end - end - - def authorize_admin_group! - unless can?(current_user, :admin_group, group) - return render_404 - end - end - - def determine_layout - if current_user - 'group' - else - 'public_group' - end - end -end diff --git a/app/controllers/groups/avatars_controller.rb b/app/controllers/groups/avatars_controller.rb deleted file mode 100644 index 38071410f404a12b4b40ace7b181f6a5b12bb0fd..0000000000000000000000000000000000000000 --- a/app/controllers/groups/avatars_controller.rb +++ /dev/null @@ -1,12 +0,0 @@ -class Groups::AvatarsController < ApplicationController - layout "profile" - - def destroy - @group = Group.find_by(path: params[:group_id]) - @group.remove_avatar! - - @group.save - - redirect_to edit_group_path(@group) - end -end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb deleted file mode 100644 index 265cf4f0f4a13544fa5abbec2f6398472bab068a..0000000000000000000000000000000000000000 --- a/app/controllers/groups/group_members_controller.rb +++ /dev/null @@ -1,84 +0,0 @@ -class Groups::GroupMembersController < Groups::ApplicationController - skip_before_filter :authenticate_user!, only: [:index] - before_filter :group - - # Authorize - before_filter :authorize_read_group! - before_filter :authorize_admin_group!, except: [:index, :leave] - - layout :determine_layout - - def index - @project = @group.projects.find(params[:project_id]) if params[:project_id] - @members = @group.group_members - @members = @members.non_invite unless can?(current_user, :admin_group, @group) - - if params[:search].present? - users = @group.users.search(params[:search]).to_a - @members = @members.where(user_id: users) - end - - @members = @members.order('access_level DESC').page(params[:page]).per(50) - @group_member = GroupMember.new - end - - def create - @group.add_users(params[:user_ids].split(','), params[:access_level], current_user) - - redirect_to group_group_members_path(@group), notice: 'Users were successfully added.' - end - - def update - @member = @group.group_members.find(params[:id]) - @member.update_attributes(member_params) - end - - def destroy - @group_member = @group.group_members.find(params[:id]) - - if can?(current_user, :destroy_group_member, @group_member) # May fail if last owner. - @group_member.destroy - respond_to do |format| - format.html { redirect_to group_group_members_path(@group), notice: 'User was successfully removed from group.' } - format.js { render nothing: true } - end - else - return render_403 - end - end - - def resend_invite - redirect_path = group_group_members_path(@group) - - @group_member = @group.group_members.find(params[:id]) - - if @group_member.invite? - @group_member.resend_invite - - redirect_to redirect_path, notice: 'The invitation was successfully resent.' - else - redirect_to redirect_path, alert: 'The invitation has already been accepted.' - end - end - - def leave - @group_member = @group.group_members.where(user_id: current_user.id).first - - if can?(current_user, :destroy_group_member, @group_member) - @group_member.destroy - redirect_to(dashboard_groups_path, notice: "You left #{group.name} group.") - else - return render_403 - end - end - - protected - - def group - @group ||= Group.find_by(path: params[:group_id]) - end - - def member_params - params.require(:group_member).permit(:access_level, :user_id) - end -end diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb deleted file mode 100644 index 546ff2cc71fd26007473436b242e203b57858e09..0000000000000000000000000000000000000000 --- a/app/controllers/groups/milestones_controller.rb +++ /dev/null @@ -1,56 +0,0 @@ -class Groups::MilestonesController < ApplicationController - layout 'group' - - before_filter :authorize_group_milestone!, only: :update - - def index - project_milestones = case params[:state] - when 'all'; state - when 'closed'; state('closed') - else state('active') - end - @group_milestones = Milestones::GroupService.new(project_milestones).execute - @group_milestones = Kaminari.paginate_array(@group_milestones).page(params[:page]).per(PER_PAGE) - end - - def show - project_milestones = Milestone.where(project_id: group.projects).order("due_date ASC") - @group_milestone = Milestones::GroupService.new(project_milestones).milestone(title) - end - - def update - project_milestones = Milestone.where(project_id: group.projects).order("due_date ASC") - @group_milestones = Milestones::GroupService.new(project_milestones).milestone(title) - - @group_milestones.milestones.each do |milestone| - Milestones::UpdateService.new(milestone.project, current_user, params[:milestone]).execute(milestone) - end - - respond_to do |format| - format.js - format.html do - redirect_to group_milestones_path(group) - end - end - end - - private - - def group - @group ||= Group.find_by(path: params[:group_id]) - end - - def title - params[:title] - end - - def state(state = nil) - conditions = { project_id: group.projects } - conditions.reverse_merge!(state: state) if state - Milestone.where(conditions).order("title ASC") - end - - def authorize_group_milestone! - return render_404 unless can?(current_user, :admin_group, group) - end -end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb deleted file mode 100644 index 7af3c077182228637d1691653336fcc6ea4f5caf..0000000000000000000000000000000000000000 --- a/app/controllers/groups_controller.rb +++ /dev/null @@ -1,145 +0,0 @@ -class GroupsController < Groups::ApplicationController - skip_before_filter :authenticate_user!, only: [:show, :issues, :merge_requests] - respond_to :html - before_filter :group, except: [:new, :create] - - # Authorize - before_filter :authorize_read_group!, except: [:new, :create] - before_filter :authorize_admin_group!, only: [:edit, :update, :destroy, :projects] - before_filter :authorize_create_group!, only: [:new, :create] - - # Load group projects - before_filter :load_projects, except: [:new, :create, :projects, :edit, :update] - before_filter :event_filter, only: :show - before_filter :set_title, only: [:new, :create] - - layout :determine_layout - - def new - @group = Group.new - end - - def create - @group = Group.new(group_params) - @group.name = @group.path.dup unless @group.name - - if @group.save - @group.add_owner(current_user) - redirect_to @group, notice: 'Group was successfully created.' - else - render action: "new" - end - end - - def show - @last_push = current_user.recent_push if current_user - @projects = @projects.includes(:namespace) - - respond_to do |format| - format.html - - format.json do - load_events - pager_json("events/_events", @events.count) - end - - format.atom do - load_events - render layout: false - end - end - end - - def merge_requests - @merge_requests = get_merge_requests_collection - @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) - @merge_requests = @merge_requests.preload(:author, :target_project) - end - - def issues - @issues = get_issues_collection - @issues = @issues.page(params[:page]).per(PER_PAGE) - @issues = @issues.preload(:author, :project) - - respond_to do |format| - format.html - format.atom { render layout: false } - end - end - - def edit - end - - def projects - @projects = @group.projects.page(params[:page]) - end - - def update - if @group.update_attributes(group_params) - redirect_to edit_group_path(@group), notice: 'Group was successfully updated.' - else - render action: "edit" - end - end - - def destroy - @group.destroy - - redirect_to root_path, notice: 'Group was removed.' - end - - protected - - def group - @group ||= Group.find_by(path: params[:id]) - end - - def load_projects - @projects ||= ProjectsFinder.new.execute(current_user, group: group).sorted_by_activity.non_archived - end - - def project_ids - @projects.pluck(:id) - end - - # Dont allow unauthorized access to group - def authorize_read_group! - unless @group and (@projects.present? or can?(current_user, :read_group, @group)) - if current_user.nil? - return authenticate_user! - else - return render_404 - end - end - end - - def authorize_create_group! - unless can?(current_user, :create_group, nil) - return render_404 - end - end - - def set_title - @title = 'New Group' - end - - def determine_layout - if [:new, :create].include?(action_name.to_sym) - 'navless' - elsif current_user - 'group' - else - 'public_group' - end - end - - def group_params - params.require(:group).permit(:name, :description, :path, :avatar) - end - - def load_events - @events = Event.in_projects(project_ids) - @events = event_filter.apply_filter(@events).with_associations - @events = @events.limit(20).offset(params[:offset] || 0) - end -end diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb deleted file mode 100644 index 93a7ace3530b87b976b5e79ea58b6c20730965b1..0000000000000000000000000000000000000000 --- a/app/controllers/import/base_controller.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Import::BaseController < ApplicationController - - private - - def get_or_create_namespace - begin - namespace = Group.create!(name: @target_namespace, path: @target_namespace, owner: current_user) - namespace.add_owner(current_user) - rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid - namespace = Namespace.find_by_path_or_name(@target_namespace) - unless current_user.can?(:create_projects, namespace) - @already_been_taken = true - return false - end - end - - namespace - end -end diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb deleted file mode 100644 index bb8d7e0235c69c253220845d9a45f1f3ae1f05bc..0000000000000000000000000000000000000000 --- a/app/controllers/import/bitbucket_controller.rb +++ /dev/null @@ -1,82 +0,0 @@ -class Import::BitbucketController < Import::BaseController - before_filter :verify_bitbucket_import_enabled - before_filter :bitbucket_auth, except: :callback - - rescue_from OAuth::Error, with: :bitbucket_unauthorized - - def callback - request_token = session.delete(:oauth_request_token) - raise "Session expired!" if request_token.nil? - - request_token.symbolize_keys! - - access_token = client.get_token(request_token, params[:oauth_verifier], callback_import_bitbucket_url) - - current_user.bitbucket_access_token = access_token.token - current_user.bitbucket_access_token_secret = access_token.secret - - current_user.save - redirect_to status_import_bitbucket_url - end - - def status - @repos = client.projects - - @already_added_projects = current_user.created_projects.where(import_type: "bitbucket") - already_added_projects_names = @already_added_projects.pluck(:import_source) - - @repos.to_a.reject!{ |repo| already_added_projects_names.include? "#{repo["owner"]}/#{repo["slug"]}" } - end - - def jobs - jobs = current_user.created_projects.where(import_type: "bitbucket").to_json(only: [:id, :import_status]) - render json: jobs - end - - def create - @repo_id = params[:repo_id] || "" - repo = client.project(@repo_id.gsub("___", "/")) - @project_name = repo["slug"] - - repo_owner = repo["owner"] - repo_owner = current_user.username if repo_owner == client.user["user"]["username"] - @target_namespace = params[:new_namespace].presence || repo_owner - - namespace = get_or_create_namespace || (render and return) - - unless Gitlab::BitbucketImport::KeyAdder.new(repo, current_user).execute - @access_denied = true - render - return - end - - @project = Gitlab::BitbucketImport::ProjectCreator.new(repo, namespace, current_user).execute - end - - private - - def client - @client ||= Gitlab::BitbucketImport::Client.new(current_user.bitbucket_access_token, current_user.bitbucket_access_token_secret) - end - - def verify_bitbucket_import_enabled - not_found! unless bitbucket_import_enabled? - end - - def bitbucket_auth - if current_user.bitbucket_access_token.blank? - go_to_bitbucket_for_permissions - end - end - - def go_to_bitbucket_for_permissions - request_token = client.request_token(callback_import_bitbucket_url) - session[:oauth_request_token] = request_token - - redirect_to client.authorize_url(request_token, callback_import_bitbucket_url) - end - - def bitbucket_unauthorized - go_to_bitbucket_for_permissions - end -end diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb deleted file mode 100644 index 87b41454c778e965b60ff3c7ddb399db0f33b9d2..0000000000000000000000000000000000000000 --- a/app/controllers/import/github_controller.rb +++ /dev/null @@ -1,68 +0,0 @@ -class Import::GithubController < Import::BaseController - before_filter :verify_github_import_enabled - before_filter :github_auth, except: :callback - - rescue_from Octokit::Unauthorized, with: :github_unauthorized - - def callback - token = client.get_token(params[:code]) - current_user.github_access_token = token - current_user.save - redirect_to status_import_github_url - end - - def status - @repos = client.repos - client.orgs.each do |org| - @repos += client.org_repos(org.login) - end - - @already_added_projects = current_user.created_projects.where(import_type: "github") - already_added_projects_names = @already_added_projects.pluck(:import_source) - - @repos.reject!{ |repo| already_added_projects_names.include? repo.full_name } - end - - def jobs - jobs = current_user.created_projects.where(import_type: "github").to_json(only: [:id, :import_status]) - render json: jobs - end - - def create - @repo_id = params[:repo_id].to_i - repo = client.repo(@repo_id) - @project_name = repo.name - - repo_owner = repo.owner.login - repo_owner = current_user.username if repo_owner == client.user.login - @target_namespace = params[:new_namespace].presence || repo_owner - - namespace = get_or_create_namespace || (render and return) - - @project = Gitlab::GithubImport::ProjectCreator.new(repo, namespace, current_user).execute - end - - private - - def client - @client ||= Gitlab::GithubImport::Client.new(current_user.github_access_token) - end - - def verify_github_import_enabled - not_found! unless github_import_enabled? - end - - def github_auth - if current_user.github_access_token.blank? - go_to_github_for_permissions - end - end - - def go_to_github_for_permissions - redirect_to client.authorize_url(callback_import_github_url) - end - - def github_unauthorized - go_to_github_for_permissions - end -end diff --git a/app/controllers/import/gitlab_controller.rb b/app/controllers/import/gitlab_controller.rb deleted file mode 100644 index bddbfded81246e8cc6bfbb02b4764b81ccead695..0000000000000000000000000000000000000000 --- a/app/controllers/import/gitlab_controller.rb +++ /dev/null @@ -1,65 +0,0 @@ -class Import::GitlabController < Import::BaseController - before_filter :verify_gitlab_import_enabled - before_filter :gitlab_auth, except: :callback - - rescue_from OAuth2::Error, with: :gitlab_unauthorized - - def callback - token = client.get_token(params[:code], callback_import_gitlab_url) - current_user.gitlab_access_token = token - current_user.save - redirect_to status_import_gitlab_url - end - - def status - @repos = client.projects - - @already_added_projects = current_user.created_projects.where(import_type: "gitlab") - already_added_projects_names = @already_added_projects.pluck(:import_source) - - @repos = @repos.to_a.reject{ |repo| already_added_projects_names.include? repo["path_with_namespace"] } - end - - def jobs - jobs = current_user.created_projects.where(import_type: "gitlab").to_json(only: [:id, :import_status]) - render json: jobs - end - - def create - @repo_id = params[:repo_id].to_i - repo = client.project(@repo_id) - @project_name = repo["name"] - - repo_owner = repo["namespace"]["path"] - repo_owner = current_user.username if repo_owner == client.user["username"] - @target_namespace = params[:new_namespace].presence || repo_owner - - namespace = get_or_create_namespace || (render and return) - - @project = Gitlab::GitlabImport::ProjectCreator.new(repo, namespace, current_user).execute - end - - private - - def client - @client ||= Gitlab::GitlabImport::Client.new(current_user.gitlab_access_token) - end - - def verify_gitlab_import_enabled - not_found! unless gitlab_import_enabled? - end - - def gitlab_auth - if current_user.gitlab_access_token.blank? - go_to_gitlab_for_permissions - end - end - - def go_to_gitlab_for_permissions - redirect_to client.authorize_url(callback_import_gitlab_url) - end - - def gitlab_unauthorized - go_to_gitlab_for_permissions - end -end diff --git a/app/controllers/import/gitorious_controller.rb b/app/controllers/import/gitorious_controller.rb deleted file mode 100644 index 6067a87ee04dbc019e4b013956ffcc8d2bb33e8e..0000000000000000000000000000000000000000 --- a/app/controllers/import/gitorious_controller.rb +++ /dev/null @@ -1,43 +0,0 @@ -class Import::GitoriousController < Import::BaseController - - def new - redirect_to client.authorize_url(callback_import_gitorious_url) - end - - def callback - session[:gitorious_repos] = params[:repos] - redirect_to status_import_gitorious_url - end - - def status - @repos = client.repos - - @already_added_projects = current_user.created_projects.where(import_type: "gitorious") - already_added_projects_names = @already_added_projects.pluck(:import_source) - - @repos.reject! { |repo| already_added_projects_names.include? repo.full_name } - end - - def jobs - jobs = current_user.created_projects.where(import_type: "gitorious").to_json(only: [:id, :import_status]) - render json: jobs - end - - def create - @repo_id = params[:repo_id] - repo = client.repo(@repo_id) - @target_namespace = params[:new_namespace].presence || repo.namespace - @project_name = repo.name - - namespace = get_or_create_namespace || (render and return) - - @project = Gitlab::GitoriousImport::ProjectCreator.new(repo, namespace, current_user).execute - end - - private - - def client - @client ||= Gitlab::GitoriousImport::Client.new(session[:gitorious_repos]) - end - -end diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb deleted file mode 100644 index 1f97ff16c5519a33086fe82120af3a298843c80b..0000000000000000000000000000000000000000 --- a/app/controllers/invites_controller.rb +++ /dev/null @@ -1,83 +0,0 @@ -class InvitesController < ApplicationController - before_filter :member - skip_before_filter :authenticate_user!, only: :decline - - respond_to :html - - layout 'navless' - - def show - - end - - def accept - if member.accept_invite!(current_user) - label, path = source_info(member.source) - - redirect_to path, notice: "You have been granted #{member.human_access} access to #{label}." - else - redirect_to :back, alert: "The invitation could not be accepted." - end - end - - def decline - if member.decline_invite! - label, _ = source_info(member.source) - - path = - if current_user - dashboard_path - else - new_user_session_path - end - - redirect_to path, notice: "You have declined the invitation to join #{label}." - else - redirect_to :back, alert: "The invitation could not be declined." - end - end - - private - - def member - return @member if defined?(@member) - - @token = params[:id] - @member = Member.find_by_invite_token(@token) - - unless @member - render_404 and return - end - - @member - end - - def authenticate_user! - return if current_user - - notice = "To accept this invitation, sign in" - notice << " or create an account" if current_application_settings.signup_enabled? - notice << "." - - store_location_for :user, request.fullpath - redirect_to new_user_session_path, notice: notice - end - - def source_info(source) - case source - when Project - project = member.source - label = "project #{project.name_with_namespace}" - path = namespace_project_path(project.namespace, project) - when Group - group = member.source - label = "group #{group.name}" - path = group_path(group) - else - label = "who knows what" - path = dashboard_path - end - - [label, path] - end -end diff --git a/app/controllers/namespaces_controller.rb b/app/controllers/namespaces_controller.rb deleted file mode 100644 index 386d103ee5a629a046d5127c34751dfff00b388b..0000000000000000000000000000000000000000 --- a/app/controllers/namespaces_controller.rb +++ /dev/null @@ -1,25 +0,0 @@ -class NamespacesController < ApplicationController - skip_before_filter :authenticate_user! - - def show - namespace = Namespace.find_by(path: params[:id]) - - if namespace - if namespace.is_a?(Group) - group = namespace - else - user = namespace.owner - end - end - - if user - redirect_to user_path(user) - elsif group && can?(current_user, :read_group, group) - redirect_to group_path(group) - elsif current_user.nil? - authenticate_user! - else - render_404 - end - end -end diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb deleted file mode 100644 index efa291d9397559f5e9c1eb1e3f0f388a51b4daa3..0000000000000000000000000000000000000000 --- a/app/controllers/oauth/applications_controller.rb +++ /dev/null @@ -1,39 +0,0 @@ -class Oauth::ApplicationsController < Doorkeeper::ApplicationsController - before_filter :authenticate_user! - layout "profile" - - def index - head :forbidden and return - end - - def create - @application = Doorkeeper::Application.new(application_params) - - @application.owner = current_user - - if @application.save - flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create]) - redirect_to oauth_application_url(@application) - else - render :new - end - end - - def destroy - if @application.destroy - flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :destroy]) - end - - redirect_to applications_profile_url - end - - private - - def set_application - @application = current_user.oauth_applications.find(params[:id]) - end - - rescue_from ActiveRecord::RecordNotFound do |exception| - render "errors/not_found", layout: "errors", status: 404 - end -end diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb deleted file mode 100644 index a57b4a60c24824950f14f8b2f74fe4d479c3b549..0000000000000000000000000000000000000000 --- a/app/controllers/oauth/authorizations_controller.rb +++ /dev/null @@ -1,57 +0,0 @@ -class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController - before_filter :authenticate_resource_owner! - layout "profile" - - def new - if pre_auth.authorizable? - if skip_authorization? || matching_token? - auth = authorization.authorize - redirect_to auth.redirect_uri - else - render "doorkeeper/authorizations/new" - end - else - render "doorkeeper/authorizations/error" - end - end - - # TODO: Handle raise invalid authorization - def create - redirect_or_render authorization.authorize - end - - def destroy - redirect_or_render authorization.deny - end - - private - - def matching_token? - Doorkeeper::AccessToken.matching_token_for(pre_auth.client, - current_resource_owner.id, - pre_auth.scopes) - end - - def redirect_or_render(auth) - if auth.redirectable? - redirect_to auth.redirect_uri - else - render json: auth.body, status: auth.status - end - end - - def pre_auth - @pre_auth ||= - Doorkeeper::OAuth::PreAuthorization.new(Doorkeeper.configuration, - server.client_via_uid, - params) - end - - def authorization - @authorization ||= strategy.request - end - - def strategy - @strategy ||= server.authorization_request(pre_auth.response_type) - end -end diff --git a/app/controllers/oauth/authorized_applications_controller.rb b/app/controllers/oauth/authorized_applications_controller.rb deleted file mode 100644 index 0b27ce7da7291db743126bae189f107e948652d5..0000000000000000000000000000000000000000 --- a/app/controllers/oauth/authorized_applications_controller.rb +++ /dev/null @@ -1,8 +0,0 @@ -class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicationsController - layout "profile" - - def destroy - Doorkeeper::AccessToken.revoke_all_for(params[:id], current_resource_owner) - redirect_to applications_profile_url, notice: I18n.t(:notice, scope: [:doorkeeper, :flash, :authorized_applications, :destroy]) - end -end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb deleted file mode 100644 index bb9d65c9ed6450acb0bc7b94b548bcfe3fa8f052..0000000000000000000000000000000000000000 --- a/app/controllers/omniauth_callbacks_controller.rb +++ /dev/null @@ -1,76 +0,0 @@ -class OmniauthCallbacksController < Devise::OmniauthCallbacksController - Gitlab.config.omniauth.providers.each do |provider| - define_method provider['name'] do - handle_omniauth - end - end - - # Extend the standard message generation to accept our custom exception - def failure_message - exception = env["omniauth.error"] - error = exception.error_reason if exception.respond_to?(:error_reason) - error ||= exception.error if exception.respond_to?(:error) - error ||= exception.message if exception.respond_to?(:message) - error ||= env["omniauth.error.type"].to_s - error.to_s.humanize if error - end - - # We only find ourselves here - # if the authentication to LDAP was successful. - def ldap - @user = Gitlab::LDAP::User.new(oauth) - @user.save if @user.changed? # will also save new users - gl_user = @user.gl_user - gl_user.remember_me = true if @user.persisted? - - # Do additional LDAP checks for the user filter and EE features - if @user.allowed? - sign_in_and_redirect(gl_user) - else - flash[:alert] = "Access denied for your LDAP account." - redirect_to new_user_session_path - end - end - - def omniauth_error - @provider = params[:provider] - @error = params[:error] - render 'errors/omniauth_error', layout: "errors", status: 422 - end - - private - - def handle_omniauth - if current_user - # Add new authentication method - current_user.identities.find_or_create_by(extern_uid: oauth['uid'], provider: oauth['provider']) - redirect_to profile_account_path, notice: 'Authentication method updated' - else - @user = Gitlab::OAuth::User.new(oauth) - @user.save - - # Only allow properly saved users to login. - if @user.persisted? && @user.valid? - sign_in_and_redirect(@user.gl_user) - else - error_message = - if @user.gl_user.errors.any? - @user.gl_user.errors.map do |attribute, message| - "#{attribute} #{message}" - end.join(", ") - else - '' - end - - redirect_to omniauth_error_path(oauth['provider'], error: error_message) and return - end - end - rescue Gitlab::OAuth::ForbiddenAction => e - flash[:notice] = e.message - redirect_to new_user_session_path - end - - def oauth - @oauth ||= request.env['omniauth.auth'] - end -end diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb deleted file mode 100644 index dcbbe5baa4b2c1888a5d040ecde785ef332924a3..0000000000000000000000000000000000000000 --- a/app/controllers/passwords_controller.rb +++ /dev/null @@ -1,18 +0,0 @@ -class PasswordsController < Devise::PasswordsController - - def create - email = resource_params[:email] - resource_found = resource_class.find_by_email(email) - if resource_found && resource_found.ldap_user? - flash[:alert] = "Cannot reset password for LDAP user." - respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name)) and return - end - - self.resource = resource_class.send_reset_password_instructions(resource_params) - if successfully_sent?(resource) - respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name)) - else - respond_with(resource) - end - end -end diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb deleted file mode 100644 index 9bd34fe22613ea5401ab2408887a3e277414ef47..0000000000000000000000000000000000000000 --- a/app/controllers/profiles/accounts_controller.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Profiles::AccountsController < ApplicationController - layout "profile" - - def show - @user = current_user - end - - def unlink - provider = params[:provider] - current_user.identities.find_by(provider: provider).destroy - redirect_to profile_account_path - end -end diff --git a/app/controllers/profiles/avatars_controller.rb b/app/controllers/profiles/avatars_controller.rb deleted file mode 100644 index 57f3bbf0627ad4d79fe4e712b2f8504ec5c3cf46..0000000000000000000000000000000000000000 --- a/app/controllers/profiles/avatars_controller.rb +++ /dev/null @@ -1,13 +0,0 @@ -class Profiles::AvatarsController < ApplicationController - layout "profile" - - def destroy - @user = current_user - @user.remove_avatar! - - @user.save - @user.reset_events_cache - - redirect_to profile_path - end -end diff --git a/app/controllers/profiles/emails_controller.rb b/app/controllers/profiles/emails_controller.rb deleted file mode 100644 index 954c98c0d9ff6775ba75fa3d9d9090a2787088de..0000000000000000000000000000000000000000 --- a/app/controllers/profiles/emails_controller.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Profiles::EmailsController < ApplicationController - layout "profile" - - def index - @primary = current_user.email - @public_email = current_user.public_email - @emails = current_user.emails - end - - def create - @email = current_user.emails.new(email_params) - - flash[:alert] = @email.errors.full_messages.first unless @email.save - - redirect_to profile_emails_url - end - - def destroy - @email = current_user.emails.find(params[:id]) - @email.destroy - - current_user.set_notification_email - current_user.set_public_email - current_user.save if current_user.notification_email_changed? or current_user.public_email_changed? - - respond_to do |format| - format.html { redirect_to profile_emails_url } - format.js { render nothing: true } - end - end - - private - - def email_params - params.require(:email).permit(:email) - end -end diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb deleted file mode 100644 index 4e2bd0a9b4b92c9730f6ec9522a8e2f1e6f992b3..0000000000000000000000000000000000000000 --- a/app/controllers/profiles/keys_controller.rb +++ /dev/null @@ -1,61 +0,0 @@ -class Profiles::KeysController < ApplicationController - layout "profile" - skip_before_filter :authenticate_user!, only: [:get_keys] - - def index - @keys = current_user.keys - end - - def show - @key = current_user.keys.find(params[:id]) - end - - def new - @key = current_user.keys.new - end - - def create - @key = current_user.keys.new(key_params) - - if @key.save - redirect_to profile_key_path(@key) - else - render 'new' - end - end - - def destroy - @key = current_user.keys.find(params[:id]) - @key.destroy - - respond_to do |format| - format.html { redirect_to profile_keys_url } - format.js { render nothing: true } - end - end - - # Get all keys of a user(params[:username]) in a text format - # Helpful for sysadmins to put in respective servers - def get_keys - if params[:username].present? - begin - user = User.find_by_username(params[:username]) - if user.present? - render text: user.all_ssh_keys.join("\n"), content_type: "text/plain" - else - render_404 and return - end - rescue => e - render text: e.message - end - else - render_404 and return - end - end - - private - - def key_params - params.require(:key).permit(:title, :key) - end -end diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb deleted file mode 100644 index 3fdcbbab61b531633827a36f336393e9d185f137..0000000000000000000000000000000000000000 --- a/app/controllers/profiles/notifications_controller.rb +++ /dev/null @@ -1,44 +0,0 @@ -class Profiles::NotificationsController < ApplicationController - layout 'profile' - - def show - @user = current_user - @notification = current_user.notification - @project_members = current_user.project_members - @group_members = current_user.group_members - end - - def update - type = params[:notification_type] - - @saved = if type == 'global' - current_user.update_attributes(user_params) - elsif type == 'group' - group_member = current_user.group_members.find(params[:notification_id]) - group_member.notification_level = params[:notification_level] - group_member.save - else - project_member = current_user.project_members.find(params[:notification_id]) - project_member.notification_level = params[:notification_level] - project_member.save - end - - respond_to do |format| - format.html do - if @saved - flash[:notice] = "Notification settings saved" - else - flash[:alert] = "Failed to save new settings" - end - - redirect_to :back - end - - format.js - end - end - - def user_params - params.require(:user).permit(:notification_email, :notification_level) - end -end diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb deleted file mode 100644 index 0c614969a3fe8626cad43d97bece80f869dd2fb1..0000000000000000000000000000000000000000 --- a/app/controllers/profiles/passwords_controller.rb +++ /dev/null @@ -1,88 +0,0 @@ -class Profiles::PasswordsController < ApplicationController - layout :determine_layout - - skip_before_filter :check_password_expiration, only: [:new, :create] - - before_filter :set_user - before_filter :set_title - before_filter :authorize_change_password! - - def new - end - - def create - unless @user.password_automatically_set || @user.valid_password?(user_params[:current_password]) - redirect_to new_profile_password_path, alert: 'You must provide a valid current password' - return - end - - new_password = user_params[:password] - new_password_confirmation = user_params[:password_confirmation] - - result = @user.update_attributes( - password: new_password, - password_confirmation: new_password_confirmation, - password_automatically_set: false - ) - - if result - @user.update_attributes(password_expires_at: nil) - redirect_to root_path, notice: 'Password successfully changed' - else - render :new - end - end - - def edit - end - - def update - password_attributes = user_params.select do |key, value| - %w(password password_confirmation).include?(key.to_s) - end - password_attributes[:password_automatically_set] = false - - unless @user.password_automatically_set || @user.valid_password?(user_params[:current_password]) - redirect_to edit_profile_password_path, alert: 'You must provide a valid current password' - return - end - - if @user.update_attributes(password_attributes) - flash[:notice] = "Password was successfully updated. Please login with it" - redirect_to new_user_session_path - else - render 'edit' - end - end - - def reset - current_user.send_reset_password_instructions - redirect_to edit_profile_password_path, notice: 'We sent you an email with reset password instructions' - end - - private - - def set_user - @user = current_user - end - - def set_title - @title = "New password" - end - - def determine_layout - if [:new, :create].include?(action_name.to_sym) - 'navless' - else - 'profile' - end - end - - def authorize_change_password! - return render_404 if @user.ldap_user? - end - - def user_params - params.require(:user).permit(:current_password, :password, :password_confirmation) - end -end diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb deleted file mode 100644 index 7f76906066d2015b096f2190ed8b35c920dc419d..0000000000000000000000000000000000000000 --- a/app/controllers/profiles_controller.rb +++ /dev/null @@ -1,76 +0,0 @@ -class ProfilesController < ApplicationController - include ActionView::Helpers::SanitizeHelper - - before_filter :user - before_filter :authorize_change_username!, only: :update_username - skip_before_filter :require_email, only: [:show, :update] - - layout 'profile' - - def show - end - - def design - end - - def applications - @applications = current_user.oauth_applications - @authorized_tokens = current_user.oauth_authorized_tokens - @authorized_apps = @authorized_tokens.map(&:application).uniq - end - - def update - user_params.except!(:email) if @user.ldap_user? - - if @user.update_attributes(user_params) - flash[:notice] = "Profile was successfully updated" - else - messages = @user.errors.full_messages.uniq.join('. ') - flash[:alert] = "Failed to update profile. #{messages}" - end - - respond_to do |format| - format.html { redirect_to :back } - format.js - end - end - - def reset_private_token - if current_user.reset_authentication_token! - flash[:notice] = "Token was successfully updated" - end - - redirect_to profile_account_path - end - - def history - @events = current_user.recent_events.page(params[:page]).per(PER_PAGE) - end - - def update_username - @user.update_attributes(username: user_params[:username]) - - respond_to do |format| - format.js - end - end - - private - - def user - @user = current_user - end - - def authorize_change_username! - return render_404 unless @user.can_change_username? - end - - def user_params - params.require(:user).permit( - :email, :password, :password_confirmation, :bio, :name, - :username, :skype, :linkedin, :twitter, :website_url, - :color_scheme_id, :theme_id, :avatar, :hide_no_ssh_key, - :hide_no_password, :location, :public_email - ) - end -end diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb deleted file mode 100644 index 4719933394fca0ef749385e01a1a2bff8c435831..0000000000000000000000000000000000000000 --- a/app/controllers/projects/application_controller.rb +++ /dev/null @@ -1,36 +0,0 @@ -class Projects::ApplicationController < ApplicationController - before_filter :project - before_filter :repository - layout :determine_layout - - def authenticate_user! - # Restrict access to Projects area only - # for non-signed users - if !current_user - id = params[:project_id] || params[:id] - project_with_namespace = "#{params[:namespace_id]}/#{id}" - @project = Project.find_with_namespace(project_with_namespace) - - return if @project && @project.public? - end - - super - end - - def determine_layout - if current_user - 'projects' - else - 'public_projects' - end - end - - def require_branch_head - unless @repository.branch_names.include?(@ref) - redirect_to( - namespace_project_tree_path(@project.namespace, @project, @ref), - notice: "This action is not allowed unless you are on top of a branch" - ) - end - end -end diff --git a/app/controllers/projects/avatars_controller.rb b/app/controllers/projects/avatars_controller.rb deleted file mode 100644 index a482b90880da9fdf0e935a4d34d657777551732a..0000000000000000000000000000000000000000 --- a/app/controllers/projects/avatars_controller.rb +++ /dev/null @@ -1,29 +0,0 @@ -class Projects::AvatarsController < Projects::ApplicationController - layout 'project' - - before_filter :project - - def show - @blob = @project.repository.blob_at_branch('master', @project.avatar_in_git) - if @blob - headers['X-Content-Type-Options'] = 'nosniff' - send_data( - @blob.data, - type: @blob.mime_type, - disposition: 'inline', - filename: @blob.name - ) - else - not_found! - end - end - - def destroy - @project.remove_avatar! - - @project.save - @project.reset_events_cache - - redirect_to edit_project_path(@project) - end -end diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb deleted file mode 100644 index a87b8270a22eb37a365f285662897d6cb8885b84..0000000000000000000000000000000000000000 --- a/app/controllers/projects/blame_controller.rb +++ /dev/null @@ -1,13 +0,0 @@ -# Controller for viewing a file's blame -class Projects::BlameController < Projects::ApplicationController - include ExtractsPath - - before_filter :require_non_empty_project - before_filter :assign_ref_vars - before_filter :authorize_download_code! - - def show - @blame = Gitlab::Git::Blame.new(@repository, @commit.id, @path) - @blob = @blame.blob - end -end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb deleted file mode 100644 index 4b7eb4df298ee50c84d315a279dbd20a1c5b0c9b..0000000000000000000000000000000000000000 --- a/app/controllers/projects/blob_controller.rb +++ /dev/null @@ -1,163 +0,0 @@ -# Controller for viewing a file's blame -class Projects::BlobController < Projects::ApplicationController - include ExtractsPath - include ActionView::Helpers::SanitizeHelper - - # Raised when given an invalid file path - class InvalidPathError < StandardError; end - - before_filter :require_non_empty_project, except: [:new, :create] - before_filter :authorize_download_code! - before_filter :authorize_push_code!, only: [:destroy] - before_filter :assign_blob_vars - before_filter :commit, except: [:new, :create] - before_filter :blob, except: [:new, :create] - before_filter :from_merge_request, only: [:edit, :update] - before_filter :after_edit_path, only: [:edit, :update] - before_filter :require_branch_head, only: [:edit, :update] - - def new - commit unless @repository.empty? - end - - def create - file_path = File.join(@path, File.basename(params[:file_name])) - result = Files::CreateService.new( - @project, - current_user, - params.merge(new_branch: sanitized_new_branch_name), - @ref, - file_path - ).execute - - if result[:status] == :success - flash[:notice] = "Your changes have been successfully committed" - ref = sanitized_new_branch_name.presence || @ref - redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(ref, file_path)) - else - flash[:alert] = result[:message] - render :new - end - end - - def show - end - - def edit - @last_commit = Gitlab::Git::Commit.last_for_path(@repository, @ref, @path).sha - end - - def update - result = Files::UpdateService. - new( - @project, - current_user, - params.merge(new_branch: sanitized_new_branch_name), - @ref, - @path - ).execute - - if result[:status] == :success - flash[:notice] = "Your changes have been successfully committed" - - if from_merge_request - from_merge_request.reload_code - end - - redirect_to after_edit_path - else - flash[:alert] = result[:message] - render :edit - end - end - - def preview - @content = params[:content] - diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true) - @diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/)) - - render layout: false - end - - def destroy - result = Files::DeleteService.new(@project, current_user, params, @ref, @path).execute - - if result[:status] == :success - flash[:notice] = "Your changes have been successfully committed" - redirect_to namespace_project_tree_path(@project.namespace, @project, - @ref) - else - flash[:alert] = result[:message] - render :show - end - end - - def diff - @form = UnfoldForm.new(params) - @lines = @blob.data.lines[@form.since - 1..@form.to - 1] - - if @form.bottom? - @match_line = '' - else - lines_length = @lines.length - 1 - line = [@form.since, lines_length].join(',') - @match_line = "@@ -#{line}+#{line} @@" - end - - render layout: false - end - - private - - def blob - @blob ||= @repository.blob_at(@commit.id, @path) - - if @blob - @blob - else - if tree = @repository.tree(@commit.id, @path) - if tree.entries.any? - redirect_to namespace_project_tree_path(@project.namespace, @project, File.join(@ref, @path)) and return - end - end - - return not_found! - end - end - - def commit - @commit = @repository.commit(@ref) - - return not_found! unless @commit - end - - def assign_blob_vars - @id = params[:id] - @ref, @path = extract_ref(@id) - - - rescue InvalidPathError - not_found! - end - - def after_edit_path - @after_edit_path ||= - if from_merge_request - diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) + - "#file-path-#{hexdigest(@path)}" - elsif sanitized_new_branch_name.present? - namespace_project_blob_path(@project.namespace, @project, File.join(sanitized_new_branch_name, @path)) - else - namespace_project_blob_path(@project.namespace, @project, @id) - end - end - - def from_merge_request - # If blob edit was initiated from merge request page - @from_merge_request ||= MergeRequest.find_by(id: params[:from_merge_request_id]) - end - - def sanitized_new_branch_name - @new_branch ||= sanitize(strip_tags(params[:new_branch])) - end -end diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb deleted file mode 100644 index f049e96e61df4fcee5ed91daf7f24c60aeb8a798..0000000000000000000000000000000000000000 --- a/app/controllers/projects/branches_controller.rb +++ /dev/null @@ -1,46 +0,0 @@ -class Projects::BranchesController < Projects::ApplicationController - include ActionView::Helpers::SanitizeHelper - # Authorize - before_filter :require_non_empty_project - before_filter :authorize_download_code! - before_filter :authorize_push_code!, only: [:create, :destroy] - - def index - @sort = params[:sort] || 'name' - @branches = @repository.branches_sorted_by(@sort) - @branches = Kaminari.paginate_array(@branches).page(params[:page]).per(PER_PAGE) - end - - def recent - @branches = @repository.recent_branches - end - - def create - branch_name = sanitize(strip_tags(params[:branch_name])) - ref = sanitize(strip_tags(params[:ref])) - result = CreateBranchService.new(project, current_user). - execute(branch_name, ref) - - if result[:status] == :success - @branch = result[:branch] - redirect_to namespace_project_tree_path(@project.namespace, @project, - @branch.name) - else - @error = result[:message] - render action: 'new' - end - end - - def destroy - DeleteBranchService.new(project, current_user).execute(params[:id]) - @branch_name = params[:id] - - respond_to do |format| - format.html do - redirect_to namespace_project_branches_path(@project.namespace, - @project) - end - format.js - end - end -end diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb deleted file mode 100644 index 87e39f1363a6acce991bf6101ca7c6fe998284a7..0000000000000000000000000000000000000000 --- a/app/controllers/projects/commit_controller.rb +++ /dev/null @@ -1,41 +0,0 @@ -# Controller for a specific Commit -# -# Not to be confused with CommitsController, plural. -class Projects::CommitController < Projects::ApplicationController - # Authorize - before_filter :require_non_empty_project - before_filter :authorize_download_code! - before_filter :commit - - def show - return git_not_found! unless @commit - - @line_notes = @project.notes.for_commit_id(commit.id).inline - @diffs = @commit.diffs - @note = @project.build_commit_note(commit) - @notes_count = @project.notes.for_commit_id(commit.id).count - @notes = @project.notes.for_commit_id(@commit.id).not_inline.fresh - @noteable = @commit - @comments_allowed = @reply_allowed = true - @comments_target = { - noteable_type: 'Commit', - commit_id: @commit.id - } - - respond_to do |format| - format.html - format.diff { render text: @commit.to_diff } - format.patch { render text: @commit.to_patch } - end - end - - def branches - @branches = @project.repository.branch_names_contains(commit.id) - @tags = @project.repository.tag_names_contains(commit.id) - render layout: false - end - - def commit - @commit ||= @project.repository.commit(params[:id]) - end -end diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb deleted file mode 100644 index 4b6ab43747625eb2dc91501b37bc7c51bd98e7e7..0000000000000000000000000000000000000000 --- a/app/controllers/projects/commits_controller.rb +++ /dev/null @@ -1,24 +0,0 @@ -require "base64" - -class Projects::CommitsController < Projects::ApplicationController - include ExtractsPath - - before_filter :require_non_empty_project - before_filter :assign_ref_vars - before_filter :authorize_download_code! - - def show - @repo = @project.repository - @limit, @offset = (params[:limit] || 40), (params[:offset] || 0) - - @commits = @repo.commits(@ref, @path, @limit, @offset) - @note_counts = Note.where(commit_id: @commits.map(&:id)). - group(:commit_id).count - - respond_to do |format| - format.html - format.json { pager_json("projects/commits/_commits", @commits.size) } - format.atom { render layout: false } - end - end -end diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb deleted file mode 100644 index 146808fa5620c93b9bbb6c85949393ccbbfc51b0..0000000000000000000000000000000000000000 --- a/app/controllers/projects/compare_controller.rb +++ /dev/null @@ -1,31 +0,0 @@ -class Projects::CompareController < Projects::ApplicationController - # Authorize - before_filter :require_non_empty_project - before_filter :authorize_download_code! - - def index - end - - def show - base_ref = params[:from] - head_ref = params[:to] - - compare_result = CompareService.new.execute( - current_user, - @project, - head_ref, - @project, - base_ref - ) - - @commits = compare_result.commits - @diffs = compare_result.diffs - @commit = @commits.last - @line_notes = [] - end - - def create - redirect_to namespace_project_compare_path(@project.namespace, @project, - params[:from], params[:to]) - end -end diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb deleted file mode 100644 index 6fba3ce299bf119ab808331105181e3e12e2fb74..0000000000000000000000000000000000000000 --- a/app/controllers/projects/deploy_keys_controller.rb +++ /dev/null @@ -1,65 +0,0 @@ -class Projects::DeployKeysController < Projects::ApplicationController - respond_to :html - - # Authorize - before_filter :authorize_admin_project! - - layout "project_settings" - - def index - @enabled_keys = @project.deploy_keys - - @available_keys = accessible_keys - @enabled_keys - @available_project_keys = current_user.project_deploy_keys - @enabled_keys - @available_public_keys = DeployKey.are_public - @enabled_keys - - # Public keys that are already used by another accessible project are already - # in @available_project_keys. - @available_public_keys -= @available_project_keys - end - - def show - @key = @project.deploy_keys.find(params[:id]) - end - - def new - @key = @project.deploy_keys.new - - respond_with(@key) - end - - def create - @key = DeployKey.new(deploy_key_params) - - if @key.valid? && @project.deploy_keys << @key - redirect_to namespace_project_deploy_keys_path(@project.namespace, - @project) - else - render "new" - end - end - - def enable - @key = accessible_keys.find(params[:id]) - @project.deploy_keys << @key - - redirect_to namespace_project_deploy_keys_path(@project.namespace, - @project) - end - - def disable - @project.deploy_keys_projects.find_by(deploy_key_id: params[:id]).destroy - - redirect_to :back - end - - protected - - def accessible_keys - @accessible_keys ||= current_user.accessible_deploy_keys - end - - def deploy_key_params - params.require(:deploy_key).permit(:key, :title) - end -end diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb deleted file mode 100644 index 21a151a426e57fe3295f40061123ad63ee04f6a1..0000000000000000000000000000000000000000 --- a/app/controllers/projects/forks_controller.rb +++ /dev/null @@ -1,25 +0,0 @@ -class Projects::ForksController < Projects::ApplicationController - # Authorize - before_filter :require_non_empty_project - before_filter :authorize_download_code! - - def new - @namespaces = current_user.manageable_namespaces - @namespaces.delete(@project.namespace) - end - - def create - namespace = Namespace.find(params[:namespace_key]) - @forked_project = ::Projects::ForkService.new(project, current_user, namespace: namespace).execute - - if @forked_project.saved? && @forked_project.forked? - redirect_to( - namespace_project_path(@forked_project.namespace, @forked_project), - notice: 'Project was successfully forked.' - ) - else - @title = 'Fork project' - render :error - end - end -end diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb deleted file mode 100644 index 6e54af356e0c96c8e1d60b9e62b0060baf6e4efc..0000000000000000000000000000000000000000 --- a/app/controllers/projects/graphs_controller.rb +++ /dev/null @@ -1,39 +0,0 @@ -class Projects::GraphsController < Projects::ApplicationController - # Authorize - before_filter :require_non_empty_project - before_filter :authorize_download_code! - - def show - respond_to do |format| - format.html - format.json do - fetch_graph - end - end - end - - def commits - @commits = @project.repository.commits(nil, nil, 2000, 0, true) - @commits_graph = Gitlab::Graphs::Commits.new(@commits) - @commits_per_week_days = @commits_graph.commits_per_week_days - @commits_per_time = @commits_graph.commits_per_time - @commits_per_month = @commits_graph.commits_per_month - end - - private - - def fetch_graph - @commits = @project.repository.commits(nil, nil, 6000, 0, true) - @log = [] - - @commits.each do |commit| - @log << { - author_name: commit.author_name, - author_email: commit.author_email, - date: commit.committed_date.strftime("%Y-%m-%d") - } - end - - render json: @log.to_json - end -end diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb deleted file mode 100644 index ba95bb13e1fbae73408a512da0948705f61c073a..0000000000000000000000000000000000000000 --- a/app/controllers/projects/hooks_controller.rb +++ /dev/null @@ -1,58 +0,0 @@ -class Projects::HooksController < Projects::ApplicationController - # Authorize - before_filter :authorize_admin_project! - - respond_to :html - - layout "project_settings" - - def index - @hooks = @project.hooks - @hook = ProjectHook.new - end - - def create - @hook = @project.hooks.new(hook_params) - @hook.save - - if @hook.valid? - redirect_to namespace_project_hooks_path(@project.namespace, @project) - else - @hooks = @project.hooks.select(&:persisted?) - render :index - end - end - - def test - if !@project.empty_repo? - status = TestHookService.new.execute(hook, current_user) - - if status - flash[:notice] = 'Hook successfully executed.' - else - flash[:alert] = 'Hook execution failed. '\ - 'Ensure hook URL is correct and service is up.' - end - else - flash[:alert] = 'Hook execution failed. Ensure the project has commits.' - end - - redirect_to :back - end - - def destroy - hook.destroy - - redirect_to namespace_project_hooks_path(@project.namespace, @project) - end - - private - - def hook - @hook ||= @project.hooks.find(params[:id]) - end - - def hook_params - params.require(:hook).permit(:url, :push_events, :issues_events, :merge_requests_events, :tag_push_events) - end -end diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb deleted file mode 100644 index b64491b4666b9a18cd30a24aaea42d99ed8c2893..0000000000000000000000000000000000000000 --- a/app/controllers/projects/imports_controller.rb +++ /dev/null @@ -1,51 +0,0 @@ -class Projects::ImportsController < Projects::ApplicationController - # Authorize - before_filter :authorize_admin_project! - before_filter :require_no_repo - before_filter :redirect_if_progress, except: :show - - def new - end - - def create - @project.import_url = params[:project][:import_url] - - if @project.save - @project.reload - - if @project.import_failed? - @project.import_retry - else - @project.import_start - end - end - - redirect_to namespace_project_import_path(@project.namespace, @project) - end - - def show - unless @project.import_in_progress? - if @project.import_finished? - redirect_to(project_path(@project)) and return - else - redirect_to new_namespace_project_import_path(@project.namespace, - @project) && return - end - end - end - - private - - def require_no_repo - if @project.repository_exists? && !@project.import_in_progress? - redirect_to(namespace_project_path(@project.namespace, @project)) and return - end - end - - def redirect_if_progress - if @project.import_in_progress? - redirect_to namespace_project_import_path(@project.namespace, @project) && - return - end - end -end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb deleted file mode 100644 index 88302276b5ee59974886c60a40ea47d74cdbe770..0000000000000000000000000000000000000000 --- a/app/controllers/projects/issues_controller.rb +++ /dev/null @@ -1,159 +0,0 @@ -class Projects::IssuesController < Projects::ApplicationController - before_filter :module_enabled - before_filter :issue, only: [:edit, :update, :show, :toggle_subscription] - - # Allow read any issue - before_filter :authorize_read_issue! - - # Allow write(create) issue - before_filter :authorize_write_issue!, only: [:new, :create] - - # Allow modify issue - before_filter :authorize_modify_issue!, only: [:edit, :update] - - # Allow issues bulk update - before_filter :authorize_admin_issues!, only: [:bulk_update] - - respond_to :html - - def index - terms = params['issue_search'] - @issues = get_issues_collection - @issues = @issues.full_search(terms) if terms.present? - @issues = @issues.page(params[:page]).per(PER_PAGE) - - respond_to do |format| - format.html - format.atom { render layout: false } - format.json do - render json: { - html: view_to_html_string("projects/issues/_issues") - } - end - end - end - - def new - params[:issue] ||= ActionController::Parameters.new( - assignee_id: "" - ) - - @issue = @project.issues.new(issue_params) - respond_with(@issue) - end - - def edit - respond_with(@issue) - end - - def show - @note = @project.notes.new(noteable: @issue) - @notes = @issue.notes.inc_author.fresh - @noteable = @issue - - respond_with(@issue) - end - - def create - @issue = Issues::CreateService.new(project, current_user, issue_params).execute - - respond_to do |format| - format.html do - if @issue.valid? - redirect_to issue_path(@issue) - else - render :new - end - end - format.js do |format| - @link = @issue.attachment.url.to_js - end - end - end - - def update - @issue = Issues::UpdateService.new(project, current_user, issue_params).execute(issue) - - respond_to do |format| - format.js - format.html do - if @issue.valid? - redirect_to issue_path(@issue) - else - render :edit - end - end - format.json do - render json: { - saved: @issue.valid?, - assignee_avatar_url: @issue.assignee.try(:avatar_url) - } - end - end - end - - def bulk_update - result = Issues::BulkUpdateService.new(project, current_user, bulk_update_params).execute - redirect_to :back, notice: "#{result[:count]} issues updated" - end - - def toggle_subscription - @issue.toggle_subscription(current_user) - - render nothing: true - end - - protected - - def issue - @issue ||= begin - @project.issues.find_by!(iid: params[:id]) - rescue ActiveRecord::RecordNotFound - redirect_old - end - end - - def authorize_modify_issue! - return render_404 unless can?(current_user, :modify_issue, @issue) - end - - def authorize_admin_issues! - return render_404 unless can?(current_user, :admin_issue, @project) - end - - def module_enabled - return render_404 unless @project.issues_enabled - end - - # Since iids are implemented only in 6.1 - # user may navigate to issue page using old global ids. - # - # To prevent 404 errors we provide a redirect to correct iids until 7.0 release - # - def redirect_old - issue = @project.issues.find_by(id: params[:id]) - - if issue - redirect_to issue_path(issue) - return - else - raise ActiveRecord::RecordNotFound.new - end - end - - def issue_params - params.require(:issue).permit( - :title, :assignee_id, :position, :description, - :milestone_id, :state_event, :task_num, label_ids: [] - ) - end - - def bulk_update_params - params.require(:update).permit( - :issues_ids, - :assignee_id, - :milestone_id, - :state_event - ) - end -end diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb deleted file mode 100644 index 207a01ed3b0ef6c82669fc3055397af307d69394..0000000000000000000000000000000000000000 --- a/app/controllers/projects/labels_controller.rb +++ /dev/null @@ -1,82 +0,0 @@ -class Projects::LabelsController < Projects::ApplicationController - before_filter :module_enabled - before_filter :label, only: [:edit, :update, :destroy] - before_filter :authorize_labels! - before_filter :authorize_admin_labels!, except: [:index] - - respond_to :js, :html - - def index - @labels = @project.labels.page(params[:page]).per(PER_PAGE) - end - - def new - @label = @project.labels.new - end - - def create - @label = @project.labels.create(label_params) - - if @label.valid? - redirect_to namespace_project_labels_path(@project.namespace, @project) - else - render 'new' - end - end - - def edit - end - - def update - if @label.update_attributes(label_params) - redirect_to namespace_project_labels_path(@project.namespace, @project) - else - render 'edit' - end - end - - def generate - Gitlab::IssuesLabels.generate(@project) - - if params[:redirect] == 'issues' - redirect_to namespace_project_issues_path(@project.namespace, @project) - elsif params[:redirect] == 'merge_requests' - redirect_to namespace_project_merge_requests_path(@project.namespace, - @project) - else - redirect_to namespace_project_labels_path(@project.namespace, @project) - end - end - - def destroy - @label.destroy - - respond_to do |format| - format.html do - redirect_to(namespace_project_labels_path(@project.namespace, @project), - notice: 'Label was removed') - end - format.js - end - end - - protected - - def module_enabled - unless @project.issues_enabled || @project.merge_requests_enabled - return render_404 - end - end - - def label_params - params.require(:label).permit(:title, :color) - end - - def label - @label = @project.labels.find(params[:id]) - end - - def authorize_admin_labels! - return render_404 unless can?(current_user, :admin_label, @project) - end -end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb deleted file mode 100644 index 47ce8467358b4c72804fe8ca71b79c7c28d84fac..0000000000000000000000000000000000000000 --- a/app/controllers/projects/merge_requests_controller.rb +++ /dev/null @@ -1,270 +0,0 @@ -require 'gitlab/satellite/satellite' - -class Projects::MergeRequestsController < Projects::ApplicationController - before_filter :module_enabled - before_filter :merge_request, only: [:edit, :update, :show, :diffs, :automerge, :automerge_check, :ci_status, :toggle_subscription] - before_filter :closes_issues, only: [:edit, :update, :show, :diffs] - before_filter :validates_merge_request, only: [:show, :diffs] - before_filter :define_show_vars, only: [:show, :diffs] - - # Allow read any merge_request - before_filter :authorize_read_merge_request! - - # Allow write(create) merge_request - before_filter :authorize_write_merge_request!, only: [:new, :create] - - # Allow modify merge_request - before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort] - - def index - terms = params['issue_search'] - @merge_requests = get_merge_requests_collection - @merge_requests = @merge_requests.full_search(terms) if terms.present? - @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) - - respond_to do |format| - format.html - format.json do - render json: { - html: view_to_html_string("projects/merge_requests/_merge_requests") - } - end - end - end - - def show - @note_counts = Note.where(commit_id: @merge_request.commits.map(&:id)). - group(:commit_id).count - - respond_to do |format| - format.html - format.json { render json: @merge_request } - format.diff { render text: @merge_request.to_diff(current_user) } - format.patch { render text: @merge_request.to_patch(current_user) } - end - end - - def diffs - @commit = @merge_request.last_commit - @comments_allowed = @reply_allowed = true - @comments_target = { - noteable_type: 'MergeRequest', - noteable_id: @merge_request.id - } - @line_notes = @merge_request.notes.where("line_code is not null") - - respond_to do |format| - format.html - format.json { render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") } } - end - end - - def new - params[:merge_request] ||= ActionController::Parameters.new(source_project: @project) - @merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params).execute - - @target_branches = if @merge_request.target_project - @merge_request.target_project.repository.branch_names - else - [] - end - - @target_project = merge_request.target_project - @source_project = merge_request.source_project - @commits = @merge_request.compare_commits - @commit = @merge_request.compare_commits.last - @diffs = @merge_request.compare_diffs - @note_counts = Note.where(commit_id: @commits.map(&:id)). - group(:commit_id).count - end - - def edit - @source_project = @merge_request.source_project - @target_project = @merge_request.target_project - @target_branches = @merge_request.target_project.repository.branch_names - end - - def create - @target_branches ||= [] - @merge_request = MergeRequests::CreateService.new(project, current_user, merge_request_params).execute - - if @merge_request.valid? - redirect_to(merge_request_path(@merge_request)) - else - @source_project = @merge_request.source_project - @target_project = @merge_request.target_project - render action: "new" - end - end - - def update - @merge_request = MergeRequests::UpdateService.new(project, current_user, merge_request_params).execute(@merge_request) - - if @merge_request.valid? - respond_to do |format| - format.js - format.html do - redirect_to([@merge_request.target_project.namespace.becomes(Namespace), - @merge_request.target_project, @merge_request]) - end - format.json do - render json: { - saved: @merge_request.valid?, - assignee_avatar_url: @merge_request.assignee.try(:avatar_url) - } - end - end - else - render "edit" - end - end - - def automerge_check - if @merge_request.unchecked? - @merge_request.check_if_can_be_merged - end - - render json: { merge_status: @merge_request.merge_status_name } - end - - def automerge - return access_denied! unless allowed_to_merge? - - if @merge_request.open? && @merge_request.can_be_merged? - AutoMergeWorker.perform_async(@merge_request.id, current_user.id, params) - @status = true - else - @status = false - end - end - - def branch_from - #This is always source - @source_project = @merge_request.nil? ? @project : @merge_request.source_project - @commit = @repository.commit(params[:ref]) if params[:ref].present? - end - - def branch_to - @target_project = selected_target_project - @commit = @target_project.repository.commit(params[:ref]) if params[:ref].present? - end - - def update_branches - @target_project = selected_target_project - @target_branches = @target_project.repository.branch_names - - respond_to do |format| - format.js - end - end - - def ci_status - ci_service = @merge_request.source_project.ci_service - status = ci_service.commit_status(merge_request.last_commit.sha, merge_request.source_branch) - - if ci_service.respond_to?(:commit_coverage) - coverage = ci_service.commit_coverage(merge_request.last_commit.sha, merge_request.source_branch) - end - - response = { - status: status, - coverage: coverage - } - - render json: response - end - - def toggle_subscription - @merge_request.toggle_subscription(current_user) - - render nothing: true - end - - protected - - def selected_target_project - if @project.id.to_s == params[:target_project_id] || @project.forked_project_link.nil? - @project - else - @project.forked_project_link.forked_from_project - end - end - - def merge_request - @merge_request ||= @project.merge_requests.find_by!(iid: params[:id]) - end - - def closes_issues - @closes_issues ||= @merge_request.closes_issues - end - - def authorize_modify_merge_request! - return render_404 unless can?(current_user, :modify_merge_request, @merge_request) - end - - def authorize_admin_merge_request! - return render_404 unless can?(current_user, :admin_merge_request, @merge_request) - end - - def module_enabled - return render_404 unless @project.merge_requests_enabled - end - - def validates_merge_request - # If source project was removed (Ex. mr from fork to origin) - return invalid_mr unless @merge_request.source_project - - # Show git not found page - # if there is no saved commits between source & target branch - if @merge_request.commits.blank? - # and if target branch doesn't exist - return invalid_mr unless @merge_request.target_branch_exists? - - # or if source branch doesn't exist - return invalid_mr unless @merge_request.source_branch_exists? - end - end - - def define_show_vars - # Build a note object for comment form - @note = @project.notes.new(noteable: @merge_request) - @notes = @merge_request.mr_and_commit_notes.inc_author.fresh - @discussions = Note.discussions_from_notes(@notes) - @noteable = @merge_request - - # Get commits from repository - # or from cache if already merged - @commits = @merge_request.commits - - @merge_request_diff = @merge_request.merge_request_diff - @allowed_to_merge = allowed_to_merge? - @show_merge_controls = @merge_request.open? && @commits.any? && @allowed_to_merge - @source_branch = @merge_request.source_project.repository.find_branch(@merge_request.source_branch).try(:name) - - if @merge_request.locked_long_ago? - @merge_request.unlock_mr - @merge_request.close - end - end - - def allowed_to_merge? - allowed_to_push_code?(project, @merge_request.target_branch) - end - - def invalid_mr - # Render special view for MR with removed source or target branch - render 'invalid' - end - - def allowed_to_push_code?(project, branch) - ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch) - end - - def merge_request_params - params.require(:merge_request).permit( - :title, :assignee_id, :source_project_id, :source_branch, - :target_project_id, :target_branch, :milestone_id, - :state_event, :description, :task_num, label_ids: [] - ) - end -end diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb deleted file mode 100644 index b49b549547ab149278935b942996f79eeacebaca..0000000000000000000000000000000000000000 --- a/app/controllers/projects/milestones_controller.rb +++ /dev/null @@ -1,116 +0,0 @@ -class Projects::MilestonesController < Projects::ApplicationController - before_filter :module_enabled - before_filter :milestone, only: [:edit, :update, :destroy, :show, :sort_issues, :sort_merge_requests] - - # Allow read any milestone - before_filter :authorize_read_milestone! - - # Allow admin milestone - before_filter :authorize_admin_milestone!, except: [:index, :show] - - respond_to :html - - def index - @milestones = case params[:state] - when 'all'; @project.milestones.order("state, due_date DESC") - when 'closed'; @project.milestones.closed.order("due_date DESC") - else @project.milestones.active.order("due_date ASC") - end - - @milestones = @milestones.includes(:project) - @milestones = @milestones.page(params[:page]).per(PER_PAGE) - end - - def new - @milestone = @project.milestones.new - respond_with(@milestone) - end - - def edit - respond_with(@milestone) - end - - def show - @issues = @milestone.issues - @users = @milestone.participants.uniq - @merge_requests = @milestone.merge_requests - end - - def create - @milestone = Milestones::CreateService.new(project, current_user, milestone_params).execute - - if @milestone.save - redirect_to namespace_project_milestone_path(@project.namespace, - @project, @milestone) - else - render "new" - end - end - - def update - @milestone = Milestones::UpdateService.new(project, current_user, milestone_params).execute(milestone) - - respond_to do |format| - format.js - format.html do - if @milestone.valid? - redirect_to namespace_project_milestone_path(@project.namespace, - @project, @milestone) - else - render :edit - end - end - end - end - - def destroy - return access_denied! unless can?(current_user, :admin_milestone, @milestone) - - @milestone.destroy - - respond_to do |format| - format.html { redirect_to namespace_project_milestones_path } - format.js { render nothing: true } - end - end - - def sort_issues - @issues = @milestone.issues.where(id: params['sortable_issue']) - @issues.each do |issue| - issue.position = params['sortable_issue'].index(issue.id.to_s) + 1 - issue.save - end - - render json: { saved: true } - end - - def sort_merge_requests - @merge_requests = @milestone.merge_requests.where(id: params['sortable_merge_request']) - @merge_requests.each do |merge_request| - merge_request.position = params['sortable_merge_request'].index(merge_request.id.to_s) + 1 - merge_request.save - end - - render json: { saved: true } - end - - protected - - def milestone - @milestone ||= @project.milestones.find_by!(iid: params[:id]) - end - - def authorize_admin_milestone! - return render_404 unless can?(current_user, :admin_milestone, @project) - end - - def module_enabled - unless @project.issues_enabled || @project.merge_requests_enabled - return render_404 - end - end - - def milestone_params - params.require(:milestone).permit(:title, :description, :due_date, :state_event) - end -end diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb deleted file mode 100644 index 83d1c1dacae6d5c4afa83ef10bdf520c95c76d21..0000000000000000000000000000000000000000 --- a/app/controllers/projects/network_controller.rb +++ /dev/null @@ -1,18 +0,0 @@ -class Projects::NetworkController < Projects::ApplicationController - include ExtractsPath - include ApplicationHelper - - before_filter :require_non_empty_project - before_filter :assign_ref_vars - before_filter :authorize_download_code! - - def show - respond_to do |format| - format.html - - format.json do - @graph = Network::Graph.new(project, @ref, @commit, @options[:filter_ref]) - end - end - end -end diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb deleted file mode 100644 index 868629a0bc4aee1f33e7e55cc154dda8efe4217c..0000000000000000000000000000000000000000 --- a/app/controllers/projects/notes_controller.rb +++ /dev/null @@ -1,125 +0,0 @@ -class Projects::NotesController < Projects::ApplicationController - # Authorize - before_filter :authorize_read_note! - before_filter :authorize_write_note!, only: [:create] - before_filter :authorize_admin_note!, only: [:update, :destroy] - before_filter :find_current_user_notes, except: [:destroy, :delete_attachment] - - def index - current_fetched_at = Time.now.to_i - - notes_json = { notes: [], last_fetched_at: current_fetched_at } - - @notes.each do |note| - notes_json[:notes] << { - id: note.id, - html: note_to_html(note) - } - end - - render json: notes_json - end - - def create - @note = Notes::CreateService.new(project, current_user, note_params).execute - - respond_to do |format| - format.json { render_note_json(@note) } - format.html { redirect_to :back } - end - end - - def update - if note.editable? - note.update_attributes(note_params) - note.reset_events_cache - end - - respond_to do |format| - format.json { render_note_json(note) } - format.html { redirect_to :back } - end - end - - def destroy - if note.editable? - note.destroy - note.reset_events_cache - end - - respond_to do |format| - format.js { render nothing: true } - end - end - - def delete_attachment - note.remove_attachment! - note.update_attribute(:attachment, nil) - - respond_to do |format| - format.js { render nothing: true } - end - end - - private - - def note - @note ||= @project.notes.find(params[:id]) - end - - def note_to_html(note) - render_to_string( - "projects/notes/_note", - layout: false, - formats: [:html], - locals: { note: note } - ) - end - - def note_to_discussion_html(note) - render_to_string( - "projects/notes/_diff_notes_with_reply", - layout: false, - formats: [:html], - locals: { notes: [note] } - ) - end - - def note_to_discussion_with_diff_html(note) - return unless note.for_diff_line? - - render_to_string( - "projects/notes/_discussion", - layout: false, - formats: [:html], - locals: { discussion_notes: [note] } - ) - end - - def render_note_json(note) - render json: { - id: note.id, - discussion_id: note.discussion_id, - html: note_to_html(note), - discussion_html: note_to_discussion_html(note), - discussion_with_diff_html: note_to_discussion_with_diff_html(note) - } - end - - def authorize_admin_note! - return access_denied! unless can?(current_user, :admin_note, note) - end - - def note_params - params.require(:note).permit( - :note, :noteable, :noteable_id, :noteable_type, :project_id, - :attachment, :line_code, :commit_id - ) - end - - private - - def find_current_user_notes - @notes = NotesFinder.new.execute(project, current_user, params) - end -end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb deleted file mode 100644 index 72967a26ff12c6fe40f8451d1cb55ddc8e026f4c..0000000000000000000000000000000000000000 --- a/app/controllers/projects/project_members_controller.rb +++ /dev/null @@ -1,98 +0,0 @@ -class Projects::ProjectMembersController < Projects::ApplicationController - # Authorize - before_filter :authorize_admin_project!, except: :leave - - layout "project_settings" - - def index - @project_members = @project.project_members - @project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project) - - if params[:search].present? - users = @project.users.search(params[:search]).to_a - @project_members = @project_members.where(user_id: users) - end - - @project_members = @project_members.order('access_level DESC') - - @group = @project.group - if @group - @group_members = @group.group_members - @group_members = @group_members.non_invite unless can?(current_user, :admin_group, @group) - - if params[:search].present? - users = @group.users.search(params[:search]).to_a - @group_members = @group_members.where(user_id: users) - end - - @group_members = @group_members.order('access_level DESC').limit(20) - end - - @project_member = @project.project_members.new - end - - def new - @project_member = @project.project_members.new - end - - def create - @project.team.add_users(params[:user_ids].split(','), params[:access_level], current_user) - - redirect_to namespace_project_project_members_path(@project.namespace, @project) - end - - def update - @project_member = @project.project_members.find(params[:id]) - @project_member.update_attributes(member_params) - end - - def destroy - @project_member = @project.project_members.find(params[:id]) - @project_member.destroy - - respond_to do |format| - format.html do - redirect_to namespace_project_project_members_path(@project.namespace, @project) - end - format.js { render nothing: true } - end - end - - def resend_invite - redirect_path = namespace_project_project_members_path(@project.namespace, @project) - - @project_member = @project.project_members.find(params[:id]) - - if @project_member.invite? - @project_member.resend_invite - - redirect_to redirect_path, notice: 'The invitation was successfully resent.' - else - redirect_to redirect_path, alert: 'The invitation has already been accepted.' - end - end - - def leave - @project.project_members.find_by(user_id: current_user).destroy - - respond_to do |format| - format.html { redirect_to :back } - format.js { render nothing: true } - end - end - - def apply_import - giver = Project.find(params[:source_project_id]) - status = @project.team.import(giver, current_user) - notice = status ? "Successfully imported" : "Import failed" - - redirect_to(namespace_project_project_members_path(project.namespace, project), - notice: notice) - end - - protected - - def member_params - params.require(:project_member).permit(:user_id, :access_level) - end -end diff --git a/app/controllers/projects/protected_branches_controller.rb b/app/controllers/projects/protected_branches_controller.rb deleted file mode 100644 index ac36ac6fcd3902470c175f6310132f53856f25dd..0000000000000000000000000000000000000000 --- a/app/controllers/projects/protected_branches_controller.rb +++ /dev/null @@ -1,51 +0,0 @@ -class Projects::ProtectedBranchesController < Projects::ApplicationController - # Authorize - before_filter :require_non_empty_project - before_filter :authorize_admin_project! - - layout "project_settings" - - def index - @branches = @project.protected_branches.to_a - @protected_branch = @project.protected_branches.new - end - - def create - @project.protected_branches.create(protected_branch_params) - redirect_to namespace_project_protected_branches_path(@project.namespace, - @project) - end - - def update - protected_branch = @project.protected_branches.find(params[:id]) - - if protected_branch && - protected_branch.update_attributes( - developers_can_push: params[:developers_can_push] - ) - - respond_to do |format| - format.json { render json: protected_branch, status: :ok } - end - else - respond_to do |format| - format.json { render json: protected_branch.errors, status: :unprocessable_entity } - end - end - end - - def destroy - @project.protected_branches.find(params[:id]).destroy - - respond_to do |format| - format.html { redirect_to namespace_project_protected_branches_path } - format.js { render nothing: true } - end - end - - private - - def protected_branch_params - params.require(:protected_branch).permit(:name, :developers_can_push) - end -end diff --git a/app/controllers/projects/raw_controller.rb b/app/controllers/projects/raw_controller.rb deleted file mode 100644 index b1a029ce69618c432c75ee6585d38c5242eb13d0..0000000000000000000000000000000000000000 --- a/app/controllers/projects/raw_controller.rb +++ /dev/null @@ -1,37 +0,0 @@ -# Controller for viewing a file's raw -class Projects::RawController < Projects::ApplicationController - include ExtractsPath - - before_filter :require_non_empty_project - before_filter :assign_ref_vars - before_filter :authorize_download_code! - - def show - @blob = @repository.blob_at(@commit.id, @path) - - if @blob - type = get_blob_type - - headers['X-Content-Type-Options'] = 'nosniff' - - send_data( - @blob.data, - type: type, - disposition: 'inline', - filename: @blob.name - ) - else - not_found! - end - end - - private - - def get_blob_type - if @blob.text? - 'text/plain; charset=utf-8' - else - 'application/octet-stream' - end - end -end diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb deleted file mode 100644 index ec3b2b8d75a56d8d125555d5ed7fb373a8beb348..0000000000000000000000000000000000000000 --- a/app/controllers/projects/refs_controller.rb +++ /dev/null @@ -1,64 +0,0 @@ -class Projects::RefsController < Projects::ApplicationController - include ExtractsPath - - before_filter :require_non_empty_project - before_filter :assign_ref_vars - before_filter :authorize_download_code! - - def switch - respond_to do |format| - format.html do - new_path = if params[:destination] == "tree" - namespace_project_tree_path(@project.namespace, @project, - (@id)) - elsif params[:destination] == "blob" - namespace_project_blob_path(@project.namespace, @project, - (@id)) - elsif params[:destination] == "graph" - namespace_project_network_path(@project.namespace, @project, @id, @options) - else - namespace_project_commits_path(@project.namespace, @project, @id) - end - - redirect_to new_path - end - format.js do - @ref = params[:ref] - define_tree_vars - tree - render "tree" - end - end - end - - def logs_tree - @offset = if params[:offset].present? - params[:offset].to_i - else - 0 - end - - @limit = 25 - - @path = params[:path] - - contents = [] - contents.push(*tree.trees) - contents.push(*tree.blobs) - contents.push(*tree.submodules) - - @logs = contents[@offset, @limit].to_a.map do |content| - file = @path ? File.join(@path, content.name) : content.name - last_commit = @repo.last_commit_for_path(@commit.id, file) - { - file_name: content.name, - commit: last_commit - } - end - - respond_to do |format| - format.html { render_404 } - format.js - end - end -end diff --git a/app/controllers/projects/repositories_controller.rb b/app/controllers/projects/repositories_controller.rb deleted file mode 100644 index 96defb0c721c52837a77a45a434e849ace335b06..0000000000000000000000000000000000000000 --- a/app/controllers/projects/repositories_controller.rb +++ /dev/null @@ -1,28 +0,0 @@ -class Projects::RepositoriesController < Projects::ApplicationController - # Authorize - before_filter :require_non_empty_project, except: :create - before_filter :authorize_download_code! - before_filter :authorize_admin_project!, only: :create - - def create - @project.create_repository - - redirect_to project_path(@project) - end - - def archive - begin - file_path = ArchiveRepositoryService.new(@project, params[:ref], params[:format]).execute - rescue - return head :not_found - end - - if file_path - # Send file to user - response.headers["Content-Length"] = File.open(file_path).size.to_s - send_file file_path - else - redirect_to request.fullpath - end - end -end diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb deleted file mode 100644 index 9a484c109baf9d449f5cbdf88ea9ec3240927eb0..0000000000000000000000000000000000000000 --- a/app/controllers/projects/services_controller.rb +++ /dev/null @@ -1,59 +0,0 @@ -class Projects::ServicesController < Projects::ApplicationController - # Authorize - before_filter :authorize_admin_project! - before_filter :service, only: [:edit, :update, :test] - - respond_to :html - - layout "project_settings" - - def index - @project.build_missing_services - @services = @project.services.visible.reload - end - - def edit - end - - def update - if @service.update_attributes(service_params) - redirect_to( - edit_namespace_project_service_path(@project.namespace, @project, - @service.to_param, notice: - 'Successfully updated.') - ) - else - render 'edit' - end - end - - def test - data = Gitlab::PushDataBuilder.build_sample(project, current_user) - if @service.execute(data) - message = { notice: 'We sent a request to the provided URL' } - else - message = { alert: 'We tried to send a request to the provided URL but an error occured' } - end - - redirect_to :back, message - end - - private - - def service - @service ||= @project.services.find { |service| service.to_param == params[:id] } - end - - def service_params - params.require(:service).permit( - :title, :token, :type, :active, :api_key, :subdomain, - :room, :recipients, :project_url, :webhook, - :user_key, :device, :priority, :sound, :bamboo_url, :username, :password, - :build_key, :server, :teamcity_url, :build_type, - :description, :issues_url, :new_issue_url, :restrict_to_branch, :channel, - :colorize_messages, :channels, - :push_events, :issues_events, :merge_requests_events, :tag_push_events, - :note_events, :send_from_committer_email, :disable_diffs, :external_wiki_url - ) - end -end diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb deleted file mode 100644 index ed26840037360227877ddaa92fc275520f00ede8..0000000000000000000000000000000000000000 --- a/app/controllers/projects/snippets_controller.rb +++ /dev/null @@ -1,93 +0,0 @@ -class Projects::SnippetsController < Projects::ApplicationController - before_filter :module_enabled - before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw] - - # Allow read any snippet - before_filter :authorize_read_project_snippet! - - # Allow write(create) snippet - before_filter :authorize_write_project_snippet!, only: [:new, :create] - - # Allow modify snippet - before_filter :authorize_modify_project_snippet!, only: [:edit, :update] - - # Allow destroy snippet - before_filter :authorize_admin_project_snippet!, only: [:destroy] - - respond_to :html - - def index - @snippets = SnippetsFinder.new.execute(current_user, { - filter: :by_project, - project: @project - }) - end - - def new - @snippet = @project.snippets.build - end - - def create - @snippet = CreateSnippetService.new(@project, current_user, - snippet_params).execute - respond_with(@snippet, - location: namespace_project_snippet_path(@project.namespace, - @project, @snippet)) - end - - def edit - end - - def update - UpdateSnippetService.new(project, current_user, @snippet, - snippet_params).execute - respond_with(@snippet, - location: namespace_project_snippet_path(@project.namespace, - @project, @snippet)) - end - - def show - @note = @project.notes.new(noteable: @snippet) - @notes = @snippet.notes.fresh - @noteable = @snippet - end - - def destroy - return access_denied! unless can?(current_user, :admin_project_snippet, @snippet) - - @snippet.destroy - - redirect_to namespace_project_snippets_path(@project.namespace, @project) - end - - def raw - send_data( - @snippet.content, - type: 'text/plain; charset=utf-8', - disposition: 'inline', - filename: @snippet.sanitized_file_name - ) - end - - protected - - def snippet - @snippet ||= @project.snippets.find(params[:id]) - end - - def authorize_modify_project_snippet! - return render_404 unless can?(current_user, :modify_project_snippet, @snippet) - end - - def authorize_admin_project_snippet! - return render_404 unless can?(current_user, :admin_project_snippet, @snippet) - end - - def module_enabled - return render_404 unless @project.snippets_enabled - end - - def snippet_params - params.require(:project_snippet).permit(:title, :content, :file_name, :private, :visibility_level) - end -end diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb deleted file mode 100644 index 83f4937bce36838f944b786684e014cfff440f3e..0000000000000000000000000000000000000000 --- a/app/controllers/projects/tags_controller.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Projects::TagsController < Projects::ApplicationController - # Authorize - before_filter :require_non_empty_project - before_filter :authorize_download_code! - before_filter :authorize_push_code!, only: [:create] - before_filter :authorize_admin_project!, only: [:destroy] - - def index - sorted = VersionSorter.rsort(@repository.tag_names) - @tags = Kaminari.paginate_array(sorted).page(params[:page]).per(PER_PAGE) - end - - def create - result = CreateTagService.new(@project, current_user). - execute(params[:tag_name], params[:ref], params[:message]) - - if result[:status] == :success - @tag = result[:tag] - redirect_to namespace_project_tags_path(@project.namespace, @project) - else - @error = result[:message] - render action: 'new' - end - end - - def destroy - DeleteTagService.new(project, current_user).execute(params[:id]) - - respond_to do |format| - format.html do - redirect_to namespace_project_tags_path(@project.namespace, - @project) - end - format.js - end - end -end diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb deleted file mode 100644 index b23010bf59546dd664002c89c74789b466d10f3b..0000000000000000000000000000000000000000 --- a/app/controllers/projects/tree_controller.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Controller for viewing a repository's file structure -class Projects::TreeController < Projects::ApplicationController - include ExtractsPath - - before_filter :require_non_empty_project, except: [:new, :create] - before_filter :assign_ref_vars - before_filter :authorize_download_code! - - def show - if tree.entries.empty? - if @repository.blob_at(@commit.id, @path) - redirect_to( - namespace_project_blob_path(@project.namespace, @project, - File.join(@ref, @path)) - ) and return - else - return not_found! - end - end - - respond_to do |format| - format.html - # Disable cache so browser history works - format.js { no_cache_headers } - end - end -end diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb deleted file mode 100644 index aeb7f0699f577d74e4c67848608f71bb5db35672..0000000000000000000000000000000000000000 --- a/app/controllers/projects/wikis_controller.rb +++ /dev/null @@ -1,123 +0,0 @@ -require 'project_wiki' - -class Projects::WikisController < Projects::ApplicationController - before_filter :authorize_read_wiki! - before_filter :authorize_write_wiki!, only: [:edit, :create, :history] - before_filter :authorize_admin_wiki!, only: :destroy - before_filter :load_project_wiki - include WikiHelper - - def pages - @wiki_pages = Kaminari.paginate_array(@project_wiki.pages).page(params[:page]).per(PER_PAGE) - end - - def show - @page = @project_wiki.find_page(params[:id], params[:version_id]) - - if @page - render 'show' - elsif file = @project_wiki.find_file(params[:id], params[:version_id]) - if file.on_disk? - send_file file.on_disk_path, disposition: 'inline' - else - send_data( - file.raw_data, - type: file.mime_type, - disposition: 'inline', - filename: file.name - ) - end - else - return render('empty') unless can?(current_user, :write_wiki, @project) - @page = WikiPage.new(@project_wiki) - @page.title = params[:id] - - render 'edit' - end - end - - def edit - @page = @project_wiki.find_page(params[:id]) - end - - def update - @page = @project_wiki.find_page(params[:id]) - - return render('empty') unless can?(current_user, :write_wiki, @project) - - if @page.update(content, format, message) - redirect_to( - namespace_project_wiki_path(@project.namespace, @project, @page), - notice: 'Wiki was successfully updated.' - ) - else - render 'edit' - end - end - - def create - @page = WikiPage.new(@project_wiki) - - if @page.create(wiki_params) - redirect_to( - namespace_project_wiki_path(@project.namespace, @project, @page), - notice: 'Wiki was successfully updated.' - ) - else - render action: "edit" - end - end - - def history - @page = @project_wiki.find_page(params[:id]) - - unless @page - redirect_to( - namespace_project_wiki_path(@project.namespace, @project, :home), - notice: "Page not found" - ) - end - end - - def destroy - @page = @project_wiki.find_page(params[:id]) - @page.delete if @page - - redirect_to( - namespace_project_wiki_path(@project.namespace, @project, :home), - notice: "Page was successfully deleted" - ) - end - - def git_access - end - - private - - def load_project_wiki - @project_wiki = ProjectWiki.new(@project, current_user) - - # Call #wiki to make sure the Wiki Repo is initialized - @project_wiki.wiki - rescue ProjectWiki::CouldNotCreateWikiError => ex - flash[:notice] = "Could not create Wiki Repository at this time. Please try again later." - redirect_to project_path(@project) - return false - end - - def wiki_params - params[:wiki].slice(:title, :content, :format, :message) - end - - def content - params[:wiki][:content] - end - - def format - params[:wiki][:format] - end - - def message - params[:wiki][:message] - end -end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb deleted file mode 100644 index 0f28794b736e66a6c10b6f1f706beffeacb6bd9e..0000000000000000000000000000000000000000 --- a/app/controllers/projects_controller.rb +++ /dev/null @@ -1,198 +0,0 @@ -class ProjectsController < ApplicationController - prepend_before_filter :render_go_import, only: [:show] - skip_before_filter :authenticate_user!, only: [:show] - before_filter :project, except: [:new, :create] - before_filter :repository, except: [:new, :create] - - # Authorize - before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive] - before_filter :set_title, only: [:new, :create] - before_filter :event_filter, only: :show - - layout 'navless', only: [:new, :create, :fork] - - def new - @project = Project.new - end - - def edit - render 'edit', layout: 'project_settings' - end - - def create - @project = ::Projects::CreateService.new(current_user, project_params).execute - - if @project.saved? - redirect_to( - project_path(@project), - notice: 'Project was successfully created.' - ) - else - render 'new' - end - end - - def update - status = ::Projects::UpdateService.new(@project, current_user, project_params).execute - - respond_to do |format| - if status - flash[:notice] = 'Project was successfully updated.' - format.html do - redirect_to( - edit_project_path(@project), - notice: 'Project was successfully updated.' - ) - end - format.js - else - format.html { render 'edit', layout: 'project_settings' } - format.js - end - end - end - - def transfer - transfer_params = params.permit(:new_namespace_id) - ::Projects::TransferService.new(project, current_user, transfer_params).execute - if @project.errors[:namespace_id].present? - flash[:alert] = @project.errors[:namespace_id].first - end - end - - def show - if @project.import_in_progress? - redirect_to namespace_project_import_path(@project.namespace, @project) - return - end - - limit = (params[:limit] || 20).to_i - - @show_star = !(current_user && current_user.starred?(@project)) - - respond_to do |format| - format.html do - if @project.repository_exists? - if @project.empty_repo? - render 'projects/empty', layout: user_layout - else - @last_push = current_user.recent_push(@project.id) if current_user - render :show, layout: user_layout - end - else - render 'projects/no_repo', layout: user_layout - end - end - - format.json do - @events = @project.events.recent - @events = event_filter.apply_filter(@events).with_associations - @events = @events.limit(limit).offset(params[:offset] || 0) - pager_json('events/_events', @events.count) - end - end - end - - def destroy - return access_denied! unless can?(current_user, :remove_project, @project) - - ::Projects::DestroyService.new(@project, current_user, {}).execute - - respond_to do |format| - format.html do - flash[:alert] = 'Project deleted.' - - if request.referer.include?('/admin') - redirect_to admin_namespaces_projects_path - else - redirect_to dashboard_path - end - end - end - end - - def autocomplete_sources - note_type = params['type'] - note_id = params['type_id'] - autocomplete = ::Projects::AutocompleteService.new(@project) - participants = ::Projects::ParticipantsService.new(@project, current_user).execute(note_type, note_id) - - @suggestions = { - emojis: autocomplete_emojis, - issues: autocomplete.issues, - mergerequests: autocomplete.merge_requests, - members: participants - } - - respond_to do |format| - format.json { render json: @suggestions } - end - end - - def archive - return access_denied! unless can?(current_user, :archive_project, @project) - @project.archive! - - respond_to do |format| - format.html { redirect_to project_path(@project) } - end - end - - def unarchive - return access_denied! unless can?(current_user, :archive_project, @project) - @project.unarchive! - - respond_to do |format| - format.html { redirect_to project_path(@project) } - end - end - - def toggle_star - current_user.toggle_star(@project) - @project.reload - render json: { star_count: @project.star_count } - end - - def markdown_preview - render text: view_context.markdown(params[:md_text]) - end - - private - - def set_title - @title = 'New Project' - end - - def user_layout - current_user ? 'projects' : 'public_projects' - end - - def project_params - params.require(:project).permit( - :name, :path, :description, :issues_tracker, :tag_list, - :issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch, - :wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar - ) - end - - def autocomplete_emojis - Rails.cache.fetch("autocomplete-emoji-#{Gemojione::VERSION}") do - Emoji.emojis.map do |name, emoji| - { - name: name, - path: view_context.image_url("emoji/#{emoji["unicode"]}.png") - } - end - end - end - - def render_go_import - return unless params["go-get"] == "1" - - @namespace = params[:namespace_id] - @id = params[:project_id] || params[:id] - @id = @id.gsub(/\.git\Z/, "") - - render "go_import", layout: false - end -end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb deleted file mode 100644 index 38d116a4ee3595bdedee46370726c7300dfa37d9..0000000000000000000000000000000000000000 --- a/app/controllers/registrations_controller.rb +++ /dev/null @@ -1,41 +0,0 @@ -class RegistrationsController < Devise::RegistrationsController - before_filter :signup_enabled? - - def new - redirect_to(new_user_session_path) - end - - def destroy - current_user.destroy - - respond_to do |format| - format.html { redirect_to new_user_session_path, notice: "Account successfully removed." } - end - end - - protected - - def build_resource(hash=nil) - super - end - - def after_sign_up_path_for(_resource) - new_user_session_path - end - - def after_inactive_sign_up_path_for(_resource) - new_user_session_path - end - - private - - def signup_enabled? - unless current_application_settings.signup_enabled? - redirect_to(new_user_session_path) - end - end - - def sign_up_params - params.require(:user).permit(:username, :email, :name, :password, :password_confirmation) - end -end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb deleted file mode 100644 index c5828d0b2dfbc50e4e19594ae3f04946ff02a90b..0000000000000000000000000000000000000000 --- a/app/controllers/search_controller.rb +++ /dev/null @@ -1,55 +0,0 @@ -class SearchController < ApplicationController - include SearchHelper - - def show - return if params[:search].nil? || params[:search].blank? - - if params[:project_id].present? - @project = Project.find_by(id: params[:project_id]) - @project = nil unless can?(current_user, :download_code, @project) - end - - if params[:group_id].present? - @group = Group.find_by(id: params[:group_id]) - @group = nil unless can?(current_user, :read_group, @group) - end - - @scope = params[:scope] - @show_snippets = params[:snippets].eql? 'true' - - @search_results = - if @project - unless %w(blobs notes issues merge_requests wiki_blobs). - include?(@scope) - @scope = 'blobs' - end - - Search::ProjectService.new(@project, current_user, params).execute - elsif @show_snippets - unless %w(snippet_blobs snippet_titles).include?(@scope) - @scope = 'snippet_blobs' - end - - Search::SnippetService.new(current_user, params).execute - else - unless %w(projects issues merge_requests).include?(@scope) - @scope = 'projects' - end - Search::GlobalService.new(current_user, params).execute - end - @objects = @search_results.objects(@scope, params[:page]) - end - - def autocomplete - term = params[:term] - - if params[:project_id].present? - @project = Project.find_by(id: params[:project_id]) - @project = nil unless can?(current_user, :read_project, @project) - end - - @ref = params[:project_ref] if params[:project_ref].present? - - render json: search_autocomplete_opts(term).to_json - end -end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb deleted file mode 100644 index 3f11d7afe6f114d7492c9e39f438bfe851550de0..0000000000000000000000000000000000000000 --- a/app/controllers/sessions_controller.rb +++ /dev/null @@ -1,37 +0,0 @@ -class SessionsController < Devise::SessionsController - def new - redirect_path = - if request.referer.present? && (params['redirect_to_referer'] == 'yes') - referer_uri = URI(request.referer) - if referer_uri.host == Gitlab.config.gitlab.host - referer_uri.path - else - request.fullpath - end - else - request.fullpath - end - - # Prevent a 'you are already signed in' message directly after signing: - # we should never redirect to '/users/sign_in' after signing in successfully. - unless redirect_path == '/users/sign_in' - store_location_for(:redirect, redirect_path) - end - - if Gitlab.config.ldap.enabled - @ldap_servers = Gitlab::LDAP::Config.servers - end - - super - end - - def create - super do |resource| - # User has successfully signed in, so clear any unused reset tokens - if resource.reset_password_token.present? - resource.update_attributes(reset_password_token: nil, - reset_password_sent_at: nil) - end - end - end -end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb deleted file mode 100644 index cd52556b20385f00049f92bc4770fd366d550dd2..0000000000000000000000000000000000000000 --- a/app/controllers/snippets_controller.rb +++ /dev/null @@ -1,113 +0,0 @@ -class SnippetsController < ApplicationController - before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw] - - # Allow modify snippet - before_filter :authorize_modify_snippet!, only: [:edit, :update] - - # Allow destroy snippet - before_filter :authorize_admin_snippet!, only: [:destroy] - - before_filter :set_title - - skip_before_filter :authenticate_user!, only: [:index, :user_index, :show, :raw] - - respond_to :html - - layout :determine_layout - - def index - @snippets = SnippetsFinder.new.execute(current_user, filter: :all).page(params[:page]).per(PER_PAGE) - end - - def user_index - @user = User.find_by(username: params[:username]) - - render_404 and return unless @user - - @snippets = SnippetsFinder.new.execute(current_user, { - filter: :by_user, - user: @user, - scope: params[:scope] }). - page(params[:page]).per(PER_PAGE) - - if @user == current_user - render 'current_user_index' - else - render 'user_index' - end - end - - def new - @snippet = PersonalSnippet.new - end - - def create - @snippet = CreateSnippetService.new(nil, current_user, - snippet_params).execute - - respond_with @snippet.becomes(Snippet) - end - - def edit - end - - def update - UpdateSnippetService.new(nil, current_user, @snippet, - snippet_params).execute - respond_with @snippet.becomes(Snippet) - end - - def show - end - - def destroy - return access_denied! unless can?(current_user, :admin_personal_snippet, @snippet) - - @snippet.destroy - - redirect_to snippets_path - end - - def raw - send_data( - @snippet.content, - type: 'text/plain; charset=utf-8', - disposition: 'inline', - filename: @snippet.sanitized_file_name - ) - end - - protected - - def snippet - @snippet ||= if current_user - PersonalSnippet.where("author_id = ? OR visibility_level IN (?)", - current_user.id, - [Snippet::PUBLIC, Snippet::INTERNAL]). - find(params[:id]) - else - PersonalSnippet.are_public.find(params[:id]) - end - end - - def authorize_modify_snippet! - return render_404 unless can?(current_user, :modify_personal_snippet, @snippet) - end - - def authorize_admin_snippet! - return render_404 unless can?(current_user, :admin_personal_snippet, @snippet) - end - - def set_title - @title = 'Snippets' - @title_url = snippets_path - end - - def snippet_params - params.require(:personal_snippet).permit(:title, :content, :file_name, :private, :visibility_level) - end - - def determine_layout - current_user ? 'navless' : 'public_users' - end -end diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb deleted file mode 100644 index c5f3da54ea23b63338585b4242fdac5f32463cd0..0000000000000000000000000000000000000000 --- a/app/controllers/uploads_controller.rb +++ /dev/null @@ -1,71 +0,0 @@ -class UploadsController < ApplicationController - skip_before_filter :authenticate_user! - before_filter :find_model, :authorize_access! - - def show - uploader = @model.send(upload_mount) - - unless uploader.file_storage? - return redirect_to uploader.url - end - - unless uploader.file && uploader.file.exists? - return not_found! - end - - disposition = uploader.image? ? 'inline' : 'attachment' - send_file uploader.file.path, disposition: disposition - end - - private - - def find_model - unless upload_model && upload_mount - return not_found! - end - - @model = upload_model.find(params[:id]) - end - - def authorize_access! - authorized = - case @model - when Project - can?(current_user, :read_project, @model) - when Group - can?(current_user, :read_group, @model) - when Note - can?(current_user, :read_project, @model.project) - else - # No authentication required for user avatars. - true - end - - return if authorized - - if current_user - not_found! - else - authenticate_user! - end - end - - def upload_model - upload_models = { - user: User, - project: Project, - note: Note, - group: Group - } - - upload_models[params[:model].to_sym] - end - - def upload_mount - upload_mounts = %w(avatar attachment file) - - if upload_mounts.include?(params[:mounted_as]) - params[:mounted_as] - end - end -end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb deleted file mode 100644 index 679d6897ce97a38db06b7578387b431f6731c522..0000000000000000000000000000000000000000 --- a/app/controllers/users_controller.rb +++ /dev/null @@ -1,97 +0,0 @@ -class UsersController < ApplicationController - skip_before_filter :authenticate_user! - before_filter :set_user - layout :determine_layout - - def show - @contributed_projects = contributed_projects.joined(@user). - reject(&:forked?) - - @projects = @user.personal_projects. - where(id: authorized_projects_ids).includes(:namespace) - - # Collect only groups common for both users - @groups = @user.groups & GroupsFinder.new.execute(current_user) - - @title = @user.name - @title_url = user_path(@user) - - respond_to do |format| - format.html - - format.atom do - load_events - render layout: false - end - - format.json do - load_events - pager_json("events/_events", @events.count) - end - end - end - - def calendar - calendar = contributions_calendar - @timestamps = calendar.timestamps - @starting_year = calendar.starting_year - @starting_month = calendar.starting_month - - render 'calendar', layout: false - end - - def calendar_activities - @calendar_date = Date.parse(params[:date]) rescue nil - @events = [] - - if @calendar_date - @events = contributions_calendar.events_by_date(@calendar_date) - end - - render 'calendar_activities', layout: false - end - - def determine_layout - if current_user - 'navless' - else - 'public_users' - end - end - - private - - def set_user - @user = User.find_by_username!(params[:username]) - - unless current_user || @user.public_profile? - return authenticate_user! - end - end - - def authorized_projects_ids - # Projects user can view - @authorized_projects_ids ||= - ProjectsFinder.new.execute(current_user).pluck(:id) - end - - def contributed_projects - @contributed_projects = Project. - where(id: authorized_projects_ids & @user.contributed_projects_ids). - includes(:namespace) - end - - def contributions_calendar - @contributions_calendar ||= Gitlab::ContributionsCalendar. - new(contributed_projects.reject(&:forked?), @user) - end - - def load_events - # Get user activity feed for projects common for both users - @events = @user.recent_events. - where(project_id: authorized_projects_ids). - with_associations - - @events = @events.limit(20).offset(params[:offset] || 0) - end -end diff --git a/app/finders/README.md b/app/finders/README.md deleted file mode 100644 index 1f46518d23096345c48c3e11dadb860607b6cb14..0000000000000000000000000000000000000000 --- a/app/finders/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Finders - -This type of classes responsible for collection items based on different conditions. -To prevent lookup methods in models like this: - -```ruby -class Project - def issues_for_user_filtered_by(user, filter) - # A lot of logic not related to project model itself - end -end - -issues = project.issues_for_user_filtered_by(user, params) -``` - -Better use this: - -```ruby -issues = IssuesFinder.new.execute(project, user, filter) -``` - -It will help keep models thiner. diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb deleted file mode 100644 index d3597ef090192ee01f5380c84344df1303ed7b79..0000000000000000000000000000000000000000 --- a/app/finders/groups_finder.rb +++ /dev/null @@ -1,38 +0,0 @@ -class GroupsFinder - def execute(current_user, options = {}) - all_groups(current_user) - end - - private - - def all_groups(current_user) - if current_user - if current_user.authorized_groups.any? - # User has access to groups - # - # Return only: - # groups with public projects - # groups with internal projects - # groups with joined projects - # - group_ids = Project.public_and_internal_only.pluck(:namespace_id) + - current_user.authorized_groups.pluck(:id) - Group.where(id: group_ids) - else - # User has no group membership - # - # Return only: - # groups with public projects - # groups with internal projects - # - Group.where(id: Project.public_and_internal_only.pluck(:namespace_id)) - end - else - # Not authenticated - # - # Return only: - # groups with public projects - Group.where(id: Project.public_only.pluck(:namespace_id)) - end - end -end diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb deleted file mode 100644 index 2c0702073d45009026784f6539da0db3f51d7542..0000000000000000000000000000000000000000 --- a/app/finders/issuable_finder.rb +++ /dev/null @@ -1,160 +0,0 @@ -# IssuableFinder -# -# Used to filter Issues and MergeRequests collections by set of params -# -# Arguments: -# klass - actual class like Issue or MergeRequest -# current_user - which user use -# params: -# scope: 'created-by-me' or 'assigned-to-me' or 'all' -# state: 'open' or 'closed' or 'all' -# group_id: integer -# project_id: integer -# milestone_id: integer -# assignee_id: integer -# search: string -# label_name: string -# sort: string -# -require_relative 'projects_finder' - -class IssuableFinder - NONE = '0' - - attr_accessor :current_user, :params - - def execute(current_user, params) - @current_user = current_user - @params = params - - items = init_collection - items = by_scope(items) - items = by_state(items) - items = by_group(items) - items = by_project(items) - items = by_search(items) - items = by_milestone(items) - items = by_assignee(items) - items = by_author(items) - items = by_label(items) - items = sort(items) - end - - private - - def init_collection - table_name = klass.table_name - - if project - if Ability.abilities.allowed?(current_user, :read_project, project) - project.send(table_name) - else - [] - end - elsif current_user && params[:authorized_only].presence && !current_user_related? - klass.of_projects(current_user.authorized_projects).references(:project) - else - klass.of_projects(ProjectsFinder.new.execute(current_user)).references(:project) - end - end - - def by_scope(items) - case params[:scope] - when 'created-by-me', 'authored' then - items.where(author_id: current_user.id) - when 'all' then - items - when 'assigned-to-me' then - items.where(assignee_id: current_user.id) - else - raise 'You must specify default scope' - end - end - - def by_state(items) - case params[:state] - when 'closed' - items.closed - when 'all' - items - when 'opened' - items.opened - else - raise 'You must specify default state' - end - end - - def by_group(items) - if params[:group_id].present? - items = items.of_group(Group.find(params[:group_id])) - end - - items - end - - def by_project(items) - if params[:project_id].present? - items = items.of_projects(params[:project_id]) - end - - items - end - - def by_search(items) - if params[:search].present? - items = items.search(params[:search]) - end - - items - end - - def sort(items) - items.sort(params[:sort]) - end - - def by_milestone(items) - if params[:milestone_id].present? - items = items.where(milestone_id: (params[:milestone_id] == NONE ? nil : params[:milestone_id])) - end - - items - end - - def by_assignee(items) - if params[:assignee_id].present? - items = items.where(assignee_id: (params[:assignee_id] == NONE ? nil : params[:assignee_id])) - end - - items - end - - def by_author(items) - if params[:author_id].present? - items = items.where(author_id: (params[:author_id] == NONE ? nil : params[:author_id])) - end - - items - end - - def by_label(items) - if params[:label_name].present? - label_names = params[:label_name].split(",") - - item_ids = LabelLink.joins(:label). - where('labels.title in (?)', label_names). - where(target_type: klass.name).pluck(:target_id) - - items = items.where(id: item_ids) - end - - items - end - - def project - Project.where(id: params[:project_id]).first if params[:project_id].present? - end - - def current_user_related? - params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me' - end -end diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb deleted file mode 100644 index 20a2b0ce8f0dbb21d25e8941954dd8b26b0128ca..0000000000000000000000000000000000000000 --- a/app/finders/issues_finder.rb +++ /dev/null @@ -1,22 +0,0 @@ -# Finders::Issues class -# -# Used to filter Issues collections by set of params -# -# Arguments: -# current_user - which user use -# params: -# scope: 'created-by-me' or 'assigned-to-me' or 'all' -# state: 'open' or 'closed' or 'all' -# group_id: integer -# project_id: integer -# milestone_id: integer -# assignee_id: integer -# search: string -# label_name: string -# sort: string -# -class IssuesFinder < IssuableFinder - def klass - Issue - end -end diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb deleted file mode 100644 index b258216d0d4b5368621b52115da5b38b49c3b16e..0000000000000000000000000000000000000000 --- a/app/finders/merge_requests_finder.rb +++ /dev/null @@ -1,22 +0,0 @@ -# Finders::MergeRequest class -# -# Used to filter MergeRequests collections by set of params -# -# Arguments: -# current_user - which user use -# params: -# scope: 'created-by-me' or 'assigned-to-me' or 'all' -# state: 'open' or 'closed' or 'all' -# group_id: integer -# project_id: integer -# milestone_id: integer -# assignee_id: integer -# search: string -# label_name: string -# sort: string -# -class MergeRequestsFinder < IssuableFinder - def klass - MergeRequest - end -end diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb deleted file mode 100644 index ab252821b52133c5d2294d4f8ee4e530b3bcfafa..0000000000000000000000000000000000000000 --- a/app/finders/notes_finder.rb +++ /dev/null @@ -1,27 +0,0 @@ -class NotesFinder - FETCH_OVERLAP = 5.seconds - - def execute(project, current_user, params) - target_type = params[:target_type] - target_id = params[:target_id] - # Default to 0 to remain compatible with old clients - last_fetched_at = Time.at(params.fetch(:last_fetched_at, 0).to_i) - - notes = - case target_type - when "commit" - project.notes.for_commit_id(target_id).not_inline - when "issue" - project.issues.find(target_id).notes.inc_author - when "merge_request" - project.merge_requests.find(target_id).mr_and_commit_notes.inc_author - when "snippet", "project_snippet" - project.snippets.find(target_id).notes - else - raise 'invalid target_type' - end - - # Use overlapping intervals to avoid worrying about race conditions - notes.where('updated_at > ?', last_fetched_at - FETCH_OVERLAP).fresh - end -end diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb deleted file mode 100644 index c81bb51583af82d3a012f21a025d31bd2444e933..0000000000000000000000000000000000000000 --- a/app/finders/projects_finder.rb +++ /dev/null @@ -1,89 +0,0 @@ -class ProjectsFinder - def execute(current_user, options = {}) - group = options[:group] - - if group - group_projects(current_user, group) - else - all_projects(current_user) - end - end - - private - - def group_projects(current_user, group) - if current_user - if group.users.include?(current_user) - # User is group member - # - # Return ALL group projects - group.projects - else - projects_members = ProjectMember.in_projects(group.projects). - with_user(current_user) - - if projects_members.any? - # User is a project member - # - # Return only: - # public projects - # internal projects - # joined projects - # - group.projects.where( - "projects.id IN (?) OR projects.visibility_level IN (?)", - projects_members.pluck(:source_id), - Project.public_and_internal_levels - ) - else - # User has no access to group or group projects - # - # Return only: - # public projects - # internal projects - # - group.projects.public_and_internal_only - end - end - else - # Not authenticated - # - # Return only: - # public projects - group.projects.public_only - end - end - - def all_projects(current_user) - if current_user - if current_user.authorized_projects.any? - # User has access to private projects - # - # Return only: - # public projects - # internal projects - # joined projects - # - Project.where( - "projects.id IN (?) OR projects.visibility_level IN (?)", - current_user.authorized_projects.pluck(:id), - Project.public_and_internal_levels - ) - else - # User has no access to private projects - # - # Return only: - # public projects - # internal projects - # - Project.public_and_internal_only - end - else - # Not authenticated - # - # Return only: - # public projects - Project.public_only - end - end -end diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb deleted file mode 100644 index 07b5759443b2cf8346cc34f3858b3196bfa87d8b..0000000000000000000000000000000000000000 --- a/app/finders/snippets_finder.rb +++ /dev/null @@ -1,63 +0,0 @@ -class SnippetsFinder - def execute(current_user, params = {}) - filter = params[:filter] - - case filter - when :all then - snippets(current_user).fresh.non_expired - when :by_user then - by_user(current_user, params[:user], params[:scope]) - when :by_project - by_project(current_user, params[:project]) - end - end - - private - - def snippets(current_user) - if current_user - Snippet.public_and_internal - else - # Not authenticated - # - # Return only: - # public snippets - Snippet.are_public - end - end - - def by_user(current_user, user, scope) - snippets = user.snippets.fresh.non_expired - - return snippets.are_public unless current_user - - if user == current_user - case scope - when 'are_internal' then - snippets.are_internal - when 'are_private' then - snippets.are_private - when 'are_public' then - snippets.are_public - else - snippets - end - else - snippets.public_and_internal - end - end - - def by_project(current_user, project) - snippets = project.snippets.fresh.non_expired - - if current_user - if project.team.member?(current_user.id) - snippets - else - snippets.public_and_internal - end - else - snippets.are_public - end - end -end diff --git a/app/finders/trending_projects_finder.rb b/app/finders/trending_projects_finder.rb deleted file mode 100644 index a79bd47d9867de5379cd985b16cf3a0683e1fb74..0000000000000000000000000000000000000000 --- a/app/finders/trending_projects_finder.rb +++ /dev/null @@ -1,19 +0,0 @@ -class TrendingProjectsFinder - def execute(current_user, start_date = nil) - start_date ||= Date.today - 1.month - - projects = projects_for(current_user) - - # Determine trending projects based on comments count - # for period of time - ex. month - projects.joins(:notes).where('notes.created_at > ?', start_date). - select("projects.*, count(notes.id) as ncount"). - group("projects.id").reorder("ncount DESC") - end - - private - - def projects_for(current_user) - ProjectsFinder.new.execute(current_user) - end -end diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb deleted file mode 100644 index bb8d568380796f95c8039d39c983a90a5c5229af..0000000000000000000000000000000000000000 --- a/app/helpers/appearances_helper.rb +++ /dev/null @@ -1,21 +0,0 @@ -module AppearancesHelper - def brand_item - nil - end - - def brand_title - 'GitLab Community Edition' - end - - def brand_image - nil - end - - def brand_text - nil - end - - def brand_header_logo - image_tag 'logo-white.png' - end -end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb deleted file mode 100644 index 20457572a08cf9b57b866746d48bde9312497e6a..0000000000000000000000000000000000000000 --- a/app/helpers/application_helper.rb +++ /dev/null @@ -1,325 +0,0 @@ -require 'digest/md5' -require 'uri' - -module ApplicationHelper - COLOR_SCHEMES = { - 1 => 'white', - 2 => 'dark', - 3 => 'solarized-light', - 4 => 'solarized-dark', - 5 => 'monokai', - } - COLOR_SCHEMES.default = 'white' - - # Helper method to access the COLOR_SCHEMES - # - # The keys are the `color_scheme_ids` - # The values are the `name` of the scheme. - # - # The preview images are `name-scheme-preview.png` - # The stylesheets should use the css class `.name` - def color_schemes - COLOR_SCHEMES.freeze - end - - # Check if a particular controller is the current one - # - # args - One or more controller names to check - # - # Examples - # - # # On TreeController - # current_controller?(:tree) # => true - # current_controller?(:commits) # => false - # current_controller?(:commits, :tree) # => true - def current_controller?(*args) - args.any? { |v| v.to_s.downcase == controller.controller_name } - end - - # Check if a particular action is the current one - # - # args - One or more action names to check - # - # Examples - # - # # On Projects#new - # current_action?(:new) # => true - # current_action?(:create) # => false - # current_action?(:new, :create) # => true - def current_action?(*args) - args.any? { |v| v.to_s.downcase == action_name } - end - - def project_icon(project_id, options = {}) - project = - if project_id.is_a?(Project) - project = project_id - else - Project.find_with_namespace(project_id) - end - - if project.avatar_url - image_tag project.avatar_url, options - else # generated icon - project_identicon(project, options) - end - end - - def project_identicon(project, options = {}) - allowed_colors = { - red: 'FFEBEE', - purple: 'F3E5F5', - indigo: 'E8EAF6', - blue: 'E3F2FD', - teal: 'E0F2F1', - orange: 'FBE9E7', - gray: 'EEEEEE' - } - - options[:class] ||= '' - options[:class] << ' identicon' - bg_key = project.id % 7 - style = "background-color: ##{ allowed_colors.values[bg_key] }; color: #555" - - content_tag(:div, class: options[:class], style: style) do - project.name[0, 1].upcase - end - end - - def avatar_icon(user_email = '', size = nil) - user = User.find_by(email: user_email) - - if user - user.avatar_url(size) || default_avatar - else - gravatar_icon(user_email, size) - end - end - - def gravatar_icon(user_email = '', size = nil) - GravatarService.new.execute(user_email, size) || - default_avatar - end - - def default_avatar - image_path('no_avatar.png') - end - - def last_commit(project) - if project.repo_exists? - time_ago_with_tooltip(project.repository.commit.committed_date) - else - 'Never' - end - rescue - 'Never' - end - - def grouped_options_refs - repository = @project.repository - - options = [ - ['Branches', repository.branch_names], - ['Tags', VersionSorter.rsort(repository.tag_names)] - ] - - # If reference is commit id - we should add it to branch/tag selectbox - if(@ref && !options.flatten.include?(@ref) && - @ref =~ /\A[0-9a-zA-Z]{6,52}\z/) - options << ['Commit', [@ref]] - end - - grouped_options_for_select(options, @ref || @project.default_branch) - end - - def emoji_autocomplete_source - # should be an array of strings - # so to_s can be called, because it is sufficient and to_json is too slow - Emoji.names.to_s - end - - def app_theme - Gitlab::Theme.css_class_by_id(current_user.try(:theme_id)) - end - - def theme_type - Gitlab::Theme.type_css_class_by_id(current_user.try(:theme_id)) - end - - def user_color_scheme_class - COLOR_SCHEMES[current_user.try(:color_scheme_id)] if defined?(current_user) - end - - # Define whenever show last push event - # with suggestion to create MR - def show_last_push_widget?(event) - # Skip if event is not about added or modified non-master branch - return false unless event && event.last_push_to_non_root? && !event.rm_ref? - - project = event.project - - # Skip if project repo is empty or MR disabled - return false unless project && !project.empty_repo? && project.merge_requests_enabled - - # Skip if user already created appropriate MR - return false if project.merge_requests.where(source_branch: event.branch_name).opened.any? - - # Skip if user removed branch right after that - return false unless project.repository.branch_names.include?(event.branch_name) - - true - end - - def hexdigest(string) - Digest::SHA1.hexdigest string - end - - def simple_sanitize(str) - sanitize(str, tags: %w(a span)) - end - - def body_data_page - path = controller.controller_path.split('/') - namespace = path.first if path.second - - [namespace, controller.controller_name, controller.action_name].compact.join(':') - end - - # shortcut for gitlab config - def gitlab_config - Gitlab.config.gitlab - end - - # shortcut for gitlab extra config - def extra_config - Gitlab.config.extra - end - - def search_placeholder - if @project && @project.persisted? - 'Search in this project' - elsif @snippet || @snippets || @show_snippets - 'Search snippets' - elsif @group && @group.persisted? - 'Search in this group' - else - 'Search' - end - end - - def broadcast_message - BroadcastMessage.current - end - - def time_ago_with_tooltip(date, placement = 'top', html_class = 'time_ago') - capture_haml do - haml_tag :time, date.to_s, - class: html_class, datetime: date.getutc.iso8601, title: date.stamp('Aug 21, 2011 9:23pm'), - data: { toggle: 'tooltip', placement: placement } - - haml_tag :script, "$('." + html_class + "').timeago().tooltip()" - end.html_safe - end - - def render_markup(file_name, file_content) - GitHub::Markup.render(file_name, file_content). - force_encoding(file_content.encoding).html_safe - rescue RuntimeError - simple_format(file_content) - end - - def markup?(filename) - Gitlab::MarkdownHelper.markup?(filename) - end - - def gitlab_markdown?(filename) - Gitlab::MarkdownHelper.gitlab_markdown?(filename) - end - - # Overrides ActionView::Helpers::UrlHelper#link_to to add `rel="nofollow"` to - # external links - def link_to(name = nil, options = nil, html_options = {}) - if options.kind_of?(String) - if !options.start_with?('#', '/') - html_options = add_nofollow(options, html_options) - end - end - - super - end - - # Add `"rel=nofollow"` to external links - # - # link - String link to check - # html_options - Hash of `html_options` passed to `link_to` - # - # Returns `html_options`, adding `rel: nofollow` for external links - def add_nofollow(link, html_options = {}) - uri = URI(link) - - if uri && uri.absolute? && uri.host != Gitlab.config.gitlab.host - rel = html_options.fetch(:rel, '') - html_options[:rel] = (rel + ' nofollow').strip - end - - html_options - end - - def escaped_autolink(text) - auto_link ERB::Util.html_escape(text), link: :urls - end - - def promo_host - 'about.gitlab.com' - end - - def promo_url - 'https://' + promo_host - end - - def page_filter_path(options = {}) - without = options.delete(:without) - - exist_opts = { - state: params[:state], - scope: params[:scope], - label_name: params[:label_name], - milestone_id: params[:milestone_id], - assignee_id: params[:assignee_id], - author_id: params[:author_id], - sort: params[:sort], - } - - options = exist_opts.merge(options) - - if without.present? - without.each do |key| - options.delete(key) - end - end - - path = request.path - path << "?#{options.to_param}" - path - end - - def outdated_browser? - browser.ie? && browser.version.to_i < 10 - end - - def path_to_key(key, admin = false) - if admin - admin_user_key_path(@user, key) - else - profile_key_path(key) - end - end - - def nav_sidebar_class - if nav_menu_collapsed? - "page-sidebar-collapsed" - else - "page-sidebar-expanded" - end - end -end diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb deleted file mode 100644 index 241d6075c9f686d5b519cd265a7e342ee2eb30dd..0000000000000000000000000000000000000000 --- a/app/helpers/application_settings_helper.rb +++ /dev/null @@ -1,38 +0,0 @@ -module ApplicationSettingsHelper - def gravatar_enabled? - current_application_settings.gravatar_enabled? - end - - def twitter_sharing_enabled? - current_application_settings.twitter_sharing_enabled? - end - - def signup_enabled? - current_application_settings.signup_enabled? - end - - def signin_enabled? - current_application_settings.signin_enabled? - end - - def extra_sign_in_text - current_application_settings.sign_in_text - end - - # Return a group of checkboxes that use Bootstrap's button plugin for a - # toggle button effect. - def restricted_level_checkboxes(help_block_id) - Gitlab::VisibilityLevel.options.map do |name, level| - checked = restricted_visibility_levels(true).include?(level) - css_class = 'btn btn-primary' - css_class += ' active' if checked - checkbox_name = 'application_setting[restricted_visibility_levels][]' - - label_tag(checkbox_name, class: css_class) do - check_box_tag(checkbox_name, level, checked, - autocomplete: 'off', - 'aria-describedby' => help_block_id) + name - end - end - end -end diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb deleted file mode 100644 index 4ea838ca44731fef9fc818a8665a41f90a9eaf70..0000000000000000000000000000000000000000 --- a/app/helpers/blob_helper.rb +++ /dev/null @@ -1,72 +0,0 @@ -module BlobHelper - def highlight(blob_name, blob_content, nowrap = false) - formatter = Rugments::Formatters::HTML.new( - nowrap: nowrap, - cssclass: 'code highlight', - lineanchors: true, - lineanchorsid: 'LC' - ) - - begin - lexer = Rugments::Lexer.guess(filename: blob_name, source: blob_content) - rescue Rugments::Lexer::AmbiguousGuess - lexer = Rugments::Lexers::PlainText - end - - formatter.format(lexer.lex(blob_content)).html_safe - end - - def no_highlight_files - %w(credits changelog news copying copyright license authors) - end - - def edit_blob_link(project, ref, path, options = {}) - blob = - begin - project.repository.blob_at(ref, path) - rescue - nil - end - - if blob && blob.text? - text = 'Edit' - after = options[:after] || '' - from_mr = options[:from_merge_request_id] - link_opts = {} - link_opts[:from_merge_request_id] = from_mr if from_mr - cls = 'btn btn-small' - if allowed_tree_edit?(project, ref) - link_to(text, - namespace_project_edit_blob_path(project.namespace, project, - tree_join(ref, path), - link_opts), - class: cls - ) - else - content_tag :span, text, class: cls + ' disabled' - end + after.html_safe - else - '' - end - end - - def leave_edit_message - "Leave edit mode?\nAll unsaved changes will be lost." - end - - def editing_preview_title(filename) - if Gitlab::MarkdownHelper.previewable?(filename) - 'Preview' - else - 'Preview changes' - end - end - - # Return an image icon depending on the file mode and extension - # - # mode - File unix mode - # mode - File name - def blob_icon(mode, name) - icon("#{file_type_icon_class('file', mode, name)} fw") - end -end diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb deleted file mode 100644 index d6eaa7d57bcafcbf6496187e66cf58ea5252bb3d..0000000000000000000000000000000000000000 --- a/app/helpers/branches_helper.rb +++ /dev/null @@ -1,17 +0,0 @@ -module BranchesHelper - def can_remove_branch?(project, branch_name) - if project.protected_branch? branch_name - false - elsif branch_name == project.repository.root_ref - false - else - can?(current_user, :push_code, project) - end - end - - def can_push_branch?(project, branch_name) - return false unless project.repository.branch_names.include?(branch_name) - - ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch_name) - end -end diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb deleted file mode 100644 index 29ff47663dace2ed459de012e4173fd6495d42a7..0000000000000000000000000000000000000000 --- a/app/helpers/broadcast_messages_helper.rb +++ /dev/null @@ -1,9 +0,0 @@ -module BroadcastMessagesHelper - def broadcast_styling(broadcast_message) - if(broadcast_message.color || broadcast_message.font) - "background-color:#{broadcast_message.color};color:#{broadcast_message.font}" - else - "" - end - end -end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb deleted file mode 100644 index d13d80be2930b7b9a91569c028dfccabdba7565c..0000000000000000000000000000000000000000 --- a/app/helpers/commits_helper.rb +++ /dev/null @@ -1,183 +0,0 @@ -# encoding: utf-8 -module CommitsHelper - # Returns a link to the commit author. If the author has a matching user and - # is a member of the current @project it will link to the team member page. - # Otherwise it will link to the author email as specified in the commit. - # - # options: - # avatar: true will prepend the avatar image - # size: size of the avatar image in px - def commit_author_link(commit, options = {}) - commit_person_link(commit, options.merge(source: :author)) - end - - # Just like #author_link but for the committer. - def commit_committer_link(commit, options = {}) - commit_person_link(commit, options.merge(source: :committer)) - end - - def image_diff_class(diff) - if diff.deleted_file - "deleted" - elsif diff.new_file - "added" - else - nil - end - end - - def commit_to_html(commit, project, inline = true) - template = inline ? "inline_commit" : "commit" - escape_javascript(render "projects/commits/#{template}", commit: commit, project: project) unless commit.nil? - end - - # Breadcrumb links for a Project and, if applicable, a tree path - def commits_breadcrumbs - return unless @project && @ref - - # Add the root project link and the arrow icon - crumbs = content_tag(:li) do - link_to( - @project.path, - namespace_project_commits_path(@project.namespace, @project, @ref) - ) - end - - if @path - parts = @path.split('/') - - parts.each_with_index do |part, i| - crumbs << content_tag(:li) do - # The text is just the individual part, but the link needs all the parts before it - link_to( - part, - namespace_project_commits_path( - @project.namespace, - @project, - tree_join(@ref, parts[0..i].join('/')) - ) - ) - end - end - end - - crumbs.html_safe - end - - # Return Project default branch, if it present in array - # Else - first branch in array (mb last actual branch) - def commit_default_branch(project, branches) - branches.include?(project.default_branch) ? branches.delete(project.default_branch) : branches.pop - end - - # Returns the sorted alphabetically links to branches, separated by a comma - def commit_branches_links(project, branches) - branches.sort.map do |branch| - link_to( - namespace_project_tree_path(project.namespace, project, branch) - ) do - content_tag :span, class: 'label label-gray' do - icon('code-fork') + ' ' + branch - end - end - end.join(" ").html_safe - end - - # Returns the sorted links to tags, separated by a comma - def commit_tags_links(project, tags) - sorted = VersionSorter.rsort(tags) - sorted.map do |tag| - link_to( - namespace_project_commits_path(project.namespace, project, - project.repository.find_tag(tag).name) - ) do - content_tag :span, class: 'label label-gray' do - icon('tag') + ' ' + tag - end - end - end.join(" ").html_safe - end - - def link_to_browse_code(project, commit) - if current_controller?(:projects, :commits) - if @repo.blob_at(commit.id, @path) - return link_to( - "Browse File »", - namespace_project_blob_path(project.namespace, project, - tree_join(commit.id, @path)), - class: "pull-right" - ) - elsif @path.present? - return link_to( - "Browse Dir »", - namespace_project_tree_path(project.namespace, project, - tree_join(commit.id, @path)), - class: "pull-right" - ) - end - end - link_to( - "Browse Code »", - namespace_project_tree_path(project.namespace, project, commit), - class: "pull-right" - ) - end - - protected - - # Private: Returns a link to a person. If the person has a matching user and - # is a member of the current @project it will link to the team member page. - # Otherwise it will link to the person email as specified in the commit. - # - # options: - # source: one of :author or :committer - # avatar: true will prepend the avatar image - # size: size of the avatar image in px - def commit_person_link(commit, options = {}) - user = commit.send(options[:source]) - - source_name = clean(commit.send "#{options[:source]}_name".to_sym) - source_email = clean(commit.send "#{options[:source]}_email".to_sym) - - person_name = user.try(:name) || source_name - person_email = user.try(:email) || source_email - - text = - if options[:avatar] - avatar = image_tag(avatar_icon(person_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "") - %Q{#{avatar} #{person_name}} - else - person_name - end - - options = { - class: "commit-#{options[:source]}-link has_tooltip", - data: { :'original-title' => sanitize(source_email) } - } - - if user.nil? - mail_to(source_email, text.html_safe, options) - else - link_to(text.html_safe, user_path(user), options) - end - end - - def view_file_btn(commit_sha, diff, project) - link_to( - namespace_project_blob_path(project.namespace, project, - tree_join(commit_sha, diff.new_path)), - class: 'btn btn-small view-file js-view-file' - ) do - raw('View file @') + content_tag(:span, commit_sha[0..6], - class: 'commit-short-id') - end - end - - def truncate_sha(sha) - Commit.truncate_sha(sha) - end - - def clean(string) - Sanitize.clean(string, remove_contents: true) - end -end diff --git a/app/helpers/compare_helper.rb b/app/helpers/compare_helper.rb deleted file mode 100644 index 01847c6b807c1e7049d2e1f808a81185c9894de8..0000000000000000000000000000000000000000 --- a/app/helpers/compare_helper.rb +++ /dev/null @@ -1,22 +0,0 @@ -module CompareHelper - def compare_to_mr_button? - @project.merge_requests_enabled && - params[:from].present? && - params[:to].present? && - @repository.branch_names.include?(params[:from]) && - @repository.branch_names.include?(params[:to]) && - params[:from] != params[:to] && - !@refs_are_same - end - - def compare_mr_path - new_namespace_project_merge_request_path( - @project.namespace, - @project, - merge_request: { - source_branch: params[:to], - target_branch: params[:from] - } - ) - end -end diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb deleted file mode 100644 index c25b54eadc693650412f1e2280e009de6748f659..0000000000000000000000000000000000000000 --- a/app/helpers/dashboard_helper.rb +++ /dev/null @@ -1,9 +0,0 @@ -module DashboardHelper - def assigned_issues_dashboard_path - issues_dashboard_path(assignee_id: current_user.id) - end - - def assigned_mrs_dashboard_path - merge_requests_dashboard_path(assignee_id: current_user.id) - end -end diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb deleted file mode 100644 index 4f42972a4ddc0c87dd2e903602b5d72acac3e78c..0000000000000000000000000000000000000000 --- a/app/helpers/diff_helper.rb +++ /dev/null @@ -1,157 +0,0 @@ -module DiffHelper - def allowed_diff_size - if diff_hard_limit_enabled? - Commit::DIFF_HARD_LIMIT_FILES - else - Commit::DIFF_SAFE_FILES - end - end - - def safe_diff_files(diffs) - diffs.first(allowed_diff_size).map do |diff| - Gitlab::Diff::File.new(diff) - end - end - - def show_diff_size_warning?(diffs) - diffs.size > allowed_diff_size - end - - def diff_hard_limit_enabled? - # Enabling hard limit allows user to see more diff information - if params[:force_show_diff].present? - true - else - false - end - end - - def generate_line_code(file_path, line) - Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos) - end - - def parallel_diff(diff_file, index) - lines = [] - skip_next = false - - # Building array of lines - # - # [ - # left_type, left_line_number, left_line_content, left_line_code, - # right_line_type, right_line_number, right_line_content, right_line_code - # ] - # - diff_file.diff_lines.each do |line| - - full_line = line.text - type = line.type - line_code = generate_line_code(diff_file.file_path, line) - line_new = line.new_pos - line_old = line.old_pos - - next_line = diff_file.next_line(line.index) - - if next_line - next_line_code = generate_line_code(diff_file.file_path, next_line) - next_type = next_line.type - next_line = next_line.text - end - - if type == 'match' || type.nil? - # line in the right panel is the same as in the left one - line = [type, line_old, full_line, line_code, type, line_new, full_line, line_code] - lines.push(line) - elsif type == 'old' - if next_type == 'new' - # Left side has text removed, right side has text added - line = [type, line_old, full_line, line_code, next_type, line_new, next_line, next_line_code] - lines.push(line) - skip_next = true - elsif next_type == 'old' || next_type.nil? - # Left side has text removed, right side doesn't have any change - # No next line code, no new line number, no new line text - line = [type, line_old, full_line, line_code, next_type, nil, " ", nil] - lines.push(line) - end - elsif type == 'new' - if skip_next - # Change has been already included in previous line so no need to do it again - skip_next = false - next - else - # Change is only on the right side, left side has no change - line = [nil, nil, " ", line_code, type, line_new, full_line, line_code] - lines.push(line) - end - end - end - lines - end - - def unfold_bottom_class(bottom) - (bottom) ? 'js-unfold-bottom' : '' - end - - def diff_line_content(line) - if line.blank? - "  " - else - line - end - end - - def line_comments - @line_comments ||= @line_notes.select(&:active?).group_by(&:line_code) - end - - def organize_comments(type_left, type_right, line_code_left, line_code_right) - comments_left = comments_right = nil - - unless type_left.nil? && type_right == 'new' - comments_left = line_comments[line_code_left] - end - - unless type_left.nil? && type_right.nil? - comments_right = line_comments[line_code_right] - end - - [comments_left, comments_right] - end - - def inline_diff_btn - params_copy = params.dup - params_copy[:view] = 'inline' - # Always use HTML to handle case where JSON diff rendered this button - params_copy.delete(:format) - - link_to url_for(params_copy), id: "commit-diff-viewtype", class: (params[:view] != 'parallel' ? 'btn btn-sm active' : 'btn btn-sm') do - 'Inline' - end - end - - def parallel_diff_btn - params_copy = params.dup - params_copy[:view] = 'parallel' - # Always use HTML to handle case where JSON diff rendered this button - params_copy.delete(:format) - - link_to url_for(params_copy), id: "commit-diff-viewtype", class: (params[:view] == 'parallel' ? 'btn active btn-sm' : 'btn btn-sm') do - 'Side-by-side' - end - end - - def submodule_link(blob, ref) - tree, commit = submodule_links(blob, ref) - commit_id = if commit.nil? - blob.id[0..10] - else - link_to "#{blob.id[0..10]}", commit - end - - [ - content_tag(:span, link_to(truncate(blob.name, length: 40), tree)), - '@', - content_tag(:span, commit_id, class: 'monospace'), - ].join(' ').html_safe - end -end diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb deleted file mode 100644 index 0df3ecc90b7d270f141a336dec2979eebce53693..0000000000000000000000000000000000000000 --- a/app/helpers/emails_helper.rb +++ /dev/null @@ -1,38 +0,0 @@ -module EmailsHelper - - # Google Actions - # https://developers.google.com/gmail/markup/reference/go-to-action - def email_action(url) - name = action_title(url) - if name - data = { - "@context" => "http://schema.org", - "@type" => "EmailMessage", - "action" => { - "@type" => "ViewAction", - "name" => name, - "url" => url, - } - } - - content_tag :script, type: 'application/ld+json' do - data.to_json.html_safe - end - end - end - - def action_title(url) - return unless url - ["merge_requests", "issues", "commit"].each do |action| - if url.split("/").include?(action) - return "View #{action.humanize.singularize}" - end - end - end - - def color_email_diff(diffcontent) - formatter = Rugments::Formatters::HTML.new(cssclass: "highlight", inline_theme: :github) - lexer = Rugments::Lexers::Diff.new - raw formatter.format(lexer.lex(diffcontent)) - end -end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb deleted file mode 100644 index c9fd0f0362b9fb473d5934a76dd5e72f6dec8323..0000000000000000000000000000000000000000 --- a/app/helpers/events_helper.rb +++ /dev/null @@ -1,199 +0,0 @@ -module EventsHelper - def link_to_author(event) - author = event.author - - if author - link_to author.name, user_path(author.username) - else - event.author_name - end - end - - def event_action_name(event) - target = if event.target_type - if event.note? - event.note_target_type - else - event.target_type.titleize.downcase - end - else - 'project' - end - - [event.action_name, target].join(" ") - end - - def event_filter_link(key, tooltip) - key = key.to_s - active = if @event_filter.active? key - 'active' - end - - content_tag :li, class: "filter_icon #{active}" do - link_to request.path, class: 'has_tooltip event_filter_link', id: "#{key}_event_filter", 'data-original-title' => 'Filter by ' + tooltip.downcase do - icon(icon_for_event[key]) + content_tag(:span, ' ' + tooltip) - end - end - end - - def icon_for_event - { - EventFilter.push => 'upload', - EventFilter.merged => 'check-square-o', - EventFilter.comments => 'comments', - EventFilter.team => 'user', - } - end - - def event_feed_title(event) - words = [] - words << event.author_name - words << event_action_name(event) - - if event.push? - words << event.ref_type - words << event.ref_name - words << "at" - elsif event.commented? - if event.note_commit? - words << event.note_short_commit_id - else - words << "##{truncate event.note_target_iid}" - end - words << "at" - elsif event.target - words << "##{event.target_iid}:" - words << event.target.title if event.target.respond_to?(:title) - words << "at" - end - - words << event.project_name - - words.join(" ") - end - - def event_feed_url(event) - if event.issue? - namespace_project_issue_url(event.project.namespace, event.project, - event.issue) - elsif event.merge_request? - namespace_project_merge_request_url(event.project.namespace, - event.project, event.merge_request) - elsif event.note? && event.note_commit? - namespace_project_commit_url(event.project.namespace, event.project, - event.note_target) - elsif event.note? - if event.note_target - if event.note_commit? - namespace_project_commit_path(event.project.namespace, event.project, - event.note_commit_id, - anchor: dom_id(event.target)) - elsif event.note_project_snippet? - namespace_project_snippet_path(event.project.namespace, - event.project, event.note_target) - else - event_note_target_path(event) - end - end - elsif event.push? - if event.push_with_commits? && event.md_ref? - if event.commits_count > 1 - namespace_project_compare_url(event.project.namespace, event.project, - from: event.commit_from, to: - event.commit_to) - else - namespace_project_commit_url(event.project.namespace, event.project, - id: event.commit_to) - end - else - namespace_project_commits_url(event.project.namespace, event.project, - event.ref_name) - end - end - end - - def event_feed_summary(event) - if event.issue? - render "events/event_issue", issue: event.issue - elsif event.push? - render "events/event_push", event: event - elsif event.merge_request? - render "events/event_merge_request", merge_request: event.merge_request - elsif event.note? - render "events/event_note", note: event.note - end - end - - def event_note_target_path(event) - if event.note? && event.note_commit? - namespace_project_commit_path(event.project.namespace, event.project, - event.note_target) - else - polymorphic_path([event.project.namespace.becomes(Namespace), - event.project, event.note_target], - anchor: dom_id(event.target)) - end - end - - def event_note_title_html(event) - if event.note_target - if event.note_commit? - link_to( - namespace_project_commit_path(event.project.namespace, event.project, - event.note_commit_id, - anchor: dom_id(event.target)), - class: "commit_short_id" - ) do - "#{event.note_target_type} #{event.note_short_commit_id}" - end - elsif event.note_project_snippet? - link_to(namespace_project_snippet_path(event.project.namespace, - event.project, - event.note_target)) do - "#{event.note_target_type} ##{truncate event.note_target_id}" - end - else - link_to event_note_target_path(event) do - "#{event.note_target_type} ##{truncate event.note_target_iid}" - end - end - else - content_tag :strong do - "(deleted)" - end - end - end - - def event_note(text) - text = first_line_in_markdown(text, 150) - sanitize(text, tags: %w(a img b pre code p span)) - end - - def event_commit_title(message) - escape_once(truncate(message.split("\n").first, length: 70)) - rescue - "--broken encoding" - end - - def event_to_atom(xml, event) - if event.proper? - xml.entry do - event_link = event_feed_url(event) - event_title = event_feed_title(event) - event_summary = event_feed_summary(event) - - xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}" - xml.link href: event_link - xml.title truncate(event_title, length: 80) - xml.updated event.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, width: "40", height: "40", url: avatar_icon(event.author_email) - xml.author do |author| - xml.name event.author_name - xml.email event.author_email - end - - xml.summary(type: "xhtml") { |x| x << event_summary unless event_summary.nil? } - end - end - end -end diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb deleted file mode 100644 index 7616fe6bad8b9ccda5b3f2406fe25b6817a86c8b..0000000000000000000000000000000000000000 --- a/app/helpers/explore_helper.rb +++ /dev/null @@ -1,17 +0,0 @@ -module ExploreHelper - def explore_projects_filter_path(options={}) - exist_opts = { - sort: params[:sort], - scope: params[:scope], - group: params[:group], - tag: params[:tag], - visibility_level: params[:visibility_level], - } - - options = exist_opts.merge(options) - - path = request.path - path << "?#{options.to_param}" - path - end -end diff --git a/app/helpers/external_wiki_helper.rb b/app/helpers/external_wiki_helper.rb deleted file mode 100644 index 838b85afdfe573e1d605c784fe47b35731aa9894..0000000000000000000000000000000000000000 --- a/app/helpers/external_wiki_helper.rb +++ /dev/null @@ -1,11 +0,0 @@ -module ExternalWikiHelper - def get_project_wiki_path(project) - external_wiki_service = project.services. - select { |service| service.to_param == 'external_wiki' }.first - if external_wiki_service.present? && external_wiki_service.active? - external_wiki_service.properties['external_wiki_url'] - else - namespace_project_wiki_path(project.namespace, project, :home) - end - end -end diff --git a/app/helpers/git_helper.rb b/app/helpers/git_helper.rb deleted file mode 100644 index 096849552336c2495ab4d2f9fbe08c547f4737e0..0000000000000000000000000000000000000000 --- a/app/helpers/git_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -module GitHelper - def strip_gpg_signature(text) - text.gsub(/-----BEGIN PGP SIGNATURE-----(.*)-----END PGP SIGNATURE-----/m, "") - end -end diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb deleted file mode 100644 index aa1de2f50efb0731540988b2382d971e3869921c..0000000000000000000000000000000000000000 --- a/app/helpers/gitlab_markdown_helper.rb +++ /dev/null @@ -1,275 +0,0 @@ -module GitlabMarkdownHelper - include Gitlab::Markdown - - # Use this in places where you would normally use link_to(gfm(...), ...). - # - # It solves a problem occurring with nested links (i.e. - # "outer text gfm ref more outer text"). This will not be - # interpreted as intended. Browsers will parse something like - # "outer text gfm ref more outer text" (notice the last part is - # not linked any more). link_to_gfm corrects that. It wraps all parts to - # explicitly produce the correct linking behavior (i.e. - # "outer text gfm ref more outer text"). - def link_to_gfm(body, url, html_options = {}) - return "" if body.blank? - - escaped_body = if body =~ /\A\.*?}m) do |match| - "#{match}#{link_to("", url, html_options)[0..-5]}" # "".length +1 - end - - link_to(gfm_body.html_safe, url, html_options) - end - - def markdown(text, options={}) - unless @markdown && options == @options - @options = options - - # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch - rend = Redcarpet::Render::GitlabHTML.new(self, user_color_scheme_class, { - with_toc_data: true, - safe_links_only: true, - # Handled further down the line by HTML::Pipeline::SanitizationFilter - escape_html: false - }.merge(options)) - - # see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use - @markdown = Redcarpet::Markdown.new(rend, - no_intra_emphasis: true, - tables: true, - fenced_code_blocks: true, - autolink: true, - strikethrough: true, - lax_spacing: true, - space_after_headers: true, - superscript: true - ) - end - - @markdown.render(text).html_safe - end - - # Return the first line of +text+, up to +max_chars+, after parsing the line - # as Markdown. HTML tags in the parsed output are not counted toward the - # +max_chars+ limit. If the length limit falls within a tag's contents, then - # the tag contents are truncated without removing the closing tag. - def first_line_in_markdown(text, max_chars = nil) - md = markdown(text).strip - - truncate_visible(md, max_chars || md.length) if md.present? - end - - def render_wiki_content(wiki_page) - if wiki_page.format == :markdown - markdown(wiki_page.content) - else - wiki_page.formatted_content.html_safe - end - end - - def create_relative_links(text) - paths = extract_paths(text) - - paths.uniq.each do |file_path| - # If project does not have repository - # its nothing to rebuild - # - # TODO: pass project variable to markdown helper instead of using - # instance variable. Right now it generates invalid path for pages out - # of project scope. Example: search results where can be rendered markdown - # from different projects - if @repository && @repository.exists? && !@repository.empty? - new_path = rebuild_path(file_path) - # Finds quoted path so we don't replace other mentions of the string - # eg. "doc/api" will be replaced and "/home/doc/api/text" won't - text.gsub!("\"#{file_path}\"", "\"/#{new_path}\"") - end - end - - text - end - - def extract_paths(text) - links = substitute_links(text) - image_links = substitute_image_links(text) - links + image_links - end - - def substitute_links(text) - links = text.scan(//) - relative_links = links.flatten.reject{ |link| link_to_ignore? link } - relative_links - end - - def substitute_image_links(text) - links = text.scan(/ - true - else - ignored_protocols.map{ |protocol| link.include?(protocol) }.any? - end - end - - def ignored_protocols - ["http://","https://", "ftp://", "mailto:", "smb://"] - end - - def rebuild_path(file_path) - file_path = file_path.dup - file_path.gsub!(/(#.*)/, "") - id = $1 || "" - file_path = relative_file_path(file_path) - file_path = sanitize_slashes(file_path) - - [ - Gitlab.config.gitlab.relative_url_root, - @project.path_with_namespace, - path_with_ref(file_path), - file_path - ].compact.join("/").gsub(/\A\/*|\/*\z/, '') + id - end - - def sanitize_slashes(path) - path[0] = "" if path.start_with?("/") - path.chop if path.end_with?("/") - path - end - - def relative_file_path(path) - requested_path = @path - nested_path = build_nested_path(path, requested_path) - return nested_path if file_exists?(nested_path) - path - end - - # Covering a special case, when the link is referencing file in the same directory eg: - # If we are at doc/api/README.md and the README.md contains relative links like [Users](users.md) - # this takes the request path(doc/api/README.md), and replaces the README.md with users.md so the path looks like doc/api/users.md - # If we are at doc/api and the README.md shown in below the tree view - # this takes the request path(doc/api) and adds users.md so the path looks like doc/api/users.md - def build_nested_path(path, request_path) - return request_path if path == "" - return path unless request_path - if local_path(request_path) == "tree" - base = request_path.split("/").push(path) - base.join("/") - else - base = request_path.split("/") - base.pop - base.push(path).join("/") - end - end - - # Checks if the path exists in the repo - # eg. checks if doc/README.md exists, if not then link to blob - def path_with_ref(path) - if file_exists?(path) - "#{local_path(path)}/#{correct_ref}" - else - "blob/#{correct_ref}" - end - end - - def file_exists?(path) - return false if path.nil? - @repository.blob_at(current_sha, path).present? || @repository.tree(current_sha, path).entries.any? - end - - # Check if the path is pointing to a directory(tree) or a file(blob) - # eg. doc/api is directory and doc/README.md is file - def local_path(path) - return "tree" if @repository.tree(current_sha, path).entries.any? - return "raw" if @repository.blob_at(current_sha, path).image? - "blob" - end - - def current_sha - if @commit - @commit.id - elsif @repository && !@repository.empty? - if @ref - @repository.commit(@ref).try(:sha) - else - @repository.head_commit.sha - end - end - end - - # We will assume that if no ref exists we can point to master - def correct_ref - @ref ? @ref : "master" - end - - private - - # Return +text+, truncated to +max_chars+ characters, excluding any HTML - # tags. - def truncate_visible(text, max_chars) - doc = Nokogiri::HTML.fragment(text) - content_length = 0 - truncated = false - - doc.traverse do |node| - if node.text? || node.content.empty? - if truncated - node.remove - next - end - - # Handle line breaks within a node - if node.content.strip.lines.length > 1 - node.content = "#{node.content.lines.first.chomp}..." - truncated = true - end - - num_remaining = max_chars - content_length - if node.content.length > num_remaining - node.content = node.content.truncate(num_remaining) - truncated = true - end - content_length += node.content.length - end - - truncated = truncate_if_block(node, truncated) - end - - doc.to_html - end - - # Used by #truncate_visible. If +node+ is the first block element, and the - # text hasn't already been truncated, then append "..." to the node contents - # and return true. Otherwise return false. - def truncate_if_block(node, truncated) - if node.element? && node.description.block? && !truncated - node.content = "#{node.content}..." if node.next_sibling - true - else - truncated - end - end - - def cross_project_reference(project, entity) - path = project.path_with_namespace - - if entity.kind_of?(Issue) - [path, entity.iid].join('#') - elsif entity.kind_of?(MergeRequest) - [path, entity.iid].join('!') - else - raise 'Not supported type' - end - end -end diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb deleted file mode 100644 index 9703c8d9e9cb6c290d290fb67716c7c8bf89eaf2..0000000000000000000000000000000000000000 --- a/app/helpers/gitlab_routing_helper.rb +++ /dev/null @@ -1,55 +0,0 @@ -# Shorter routing method for project and project items -# Since update to rails 4.1.9 we are now allowed to use `/` in project routing -# so we use nested routing for project resources which include project and -# project namespace. To avoid writing long methods every time we define shortcuts for -# some of routing. -# -# For example instead of this: -# -# namespace_project_merge_request_path(merge_request.project.namespace, merge_request.projects, merge_request) -# -# We can simply use shortcut: -# -# merge_request_path(merge_request) -# -module GitlabRoutingHelper - def project_path(project, *args) - namespace_project_path(project.namespace, project, *args) - end - - def edit_project_path(project, *args) - edit_namespace_project_path(project.namespace, project, *args) - end - - def issue_path(entity, *args) - namespace_project_issue_path(entity.project.namespace, entity.project, entity, *args) - end - - def merge_request_path(entity, *args) - namespace_project_merge_request_path(entity.project.namespace, entity.project, entity, *args) - end - - def milestone_path(entity, *args) - namespace_project_milestone_path(entity.project.namespace, entity.project, entity, *args) - end - - def project_url(project, *args) - namespace_project_url(project.namespace, project, *args) - end - - def edit_project_url(project, *args) - edit_namespace_project_url(project.namespace, project, *args) - end - - def issue_url(entity, *args) - namespace_project_issue_url(entity.project.namespace, entity.project, entity, *args) - end - - def merge_request_url(entity, *args) - namespace_project_merge_request_url(entity.project.namespace, entity.project, entity, *args) - end - - def project_snippet_url(entity, *args) - namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args) - end -end diff --git a/app/helpers/graph_helper.rb b/app/helpers/graph_helper.rb deleted file mode 100644 index e1dda20de858708c6da9be66f40dce1149653bd0..0000000000000000000000000000000000000000 --- a/app/helpers/graph_helper.rb +++ /dev/null @@ -1,16 +0,0 @@ -module GraphHelper - def get_refs(repo, commit) - refs = "" - refs << commit.ref_names(repo).join(' ') - - # append note count - refs << "[#{@graph.notes[commit.id]}]" if @graph.notes[commit.id] > 0 - - refs - end - - def parents_zip_spaces(parents, parent_spaces) - ids = parents.map { |p| p.id } - ids.zip(parent_spaces) - end -end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb deleted file mode 100644 index add0a776a6366885eefac034113589c891d2eb5b..0000000000000000000000000000000000000000 --- a/app/helpers/groups_helper.rb +++ /dev/null @@ -1,59 +0,0 @@ -module GroupsHelper - def remove_user_from_group_message(group, member) - if member.user - "Are you sure you want to remove \"#{member.user.name}\" from \"#{group.name}\"?" - else - "Are you sure you want to revoke the invitation for \"#{member.invite_email}\" to join \"#{group.name}\"?" - end - end - - def leave_group_message(group) - "Are you sure you want to leave \"#{group}\" group?" - end - - def should_user_see_group_roles?(user, group) - if user - user.is_admin? || group.members.exists?(user_id: user.id) - else - false - end - end - - def group_head_title - title = @group.name - - title = if current_action?(:issues) - "Issues - " + title - elsif current_action?(:merge_requests) - "Merge requests - " + title - elsif current_action?(:members) - "Members - " + title - elsif current_action?(:edit) - "Settings - " + title - else - title - end - - title - end - - def group_settings_page? - if current_controller?('groups') - current_action?('edit') || current_action?('projects') - else - false - end - end - - def group_icon(group) - if group.is_a?(String) - group = Group.find_by(path: group) - end - - if group && group.avatar.present? - group.avatar.url - else - image_path('no_group_avatar.png') - end - end -end diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb deleted file mode 100644 index a9030729b4862c33a06da3362f3dcd52830faead..0000000000000000000000000000000000000000 --- a/app/helpers/icons_helper.rb +++ /dev/null @@ -1,83 +0,0 @@ -module IconsHelper - # Creates an icon tag given icon name(s) and possible icon modifiers. - # - # Right now this method simply delegates directly to `fa_icon` from the - # font-awesome-rails gem, but should we ever use a different icon pack in the - # future we won't have to change hundreds of method calls. - def icon(names, options = {}) - fa_icon(names, options) - end - - def spinner(text = nil, visible = false) - css_class = 'loading' - css_class << ' hide' unless visible - - content_tag :div, class: css_class do - icon('spinner spin') + text - end - end - - def boolean_to_icon(value) - if value.to_s == "true" - icon('circle', class: 'cgreen') - else - icon('power-off', class: 'clgray') - end - end - - def public_icon - icon('globe') - end - - def internal_icon - icon('shield') - end - - def private_icon - icon('lock') - end - - def file_type_icon_class(type, mode, name) - if type == 'folder' - icon_class = 'folder' - elsif mode == '120000' - icon_class = 'share' - else - # Guess which icon to choose based on file extension. - # If you think a file extension is missing, feel free to add it on PR - - case File.extname(name).downcase - when '.pdf' - icon_class = 'file-pdf-o' - when '.jpg', '.jpeg', '.jif', '.jfif', - '.jp2', '.jpx', '.j2k', '.j2c', - '.png', '.gif', '.tif', '.tiff', - '.svg', '.ico', '.bmp' - icon_class = 'file-image-o' - when '.zip', '.zipx', '.tar', '.gz', '.bz', '.bzip', - '.xz', '.rar', '.7z' - icon_class = 'file-archive-o' - when '.mp3', '.wma', '.ogg', '.oga', '.wav', '.flac', '.aac' - icon_class = 'file-audio-o' - when '.mp4', '.m4p', '.m4v', - '.mpg', '.mp2', '.mpeg', '.mpe', '.mpv', - '.mpg', '.mpeg', '.m2v', - '.avi', '.mkv', '.flv', '.ogv', '.mov', - '.3gp', '.3g2' - icon_class = 'file-video-o' - when '.doc', '.dot', '.docx', '.docm', '.dotx', '.dotm', '.docb' - icon_class = 'file-word-o' - when '.xls', '.xlt', '.xlm', '.xlsx', '.xlsm', '.xltx', '.xltm', - '.xlsb', '.xla', '.xlam', '.xll', '.xlw' - icon_class = 'file-excel-o' - when '.ppt', '.pot', '.pps', '.pptx', '.pptm', '.potx', '.potm', - '.ppam', '.ppsx', '.ppsm', '.sldx', '.sldm' - icon_class = 'file-powerpoint-o' - else - icon_class = 'file-text-o' - end - end - - icon_class - end -end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb deleted file mode 100644 index ad4a7612724719dc36150946ec49958037ab723d..0000000000000000000000000000000000000000 --- a/app/helpers/issues_helper.rb +++ /dev/null @@ -1,111 +0,0 @@ -module IssuesHelper - def issue_css_classes(issue) - classes = "issue" - classes << " closed" if issue.closed? - classes << " today" if issue.today? - classes - end - - # Returns an OpenStruct object suitable for use by options_from_collection_for_select - # to allow filtering issues by an unassigned User or Milestone - def unassigned_filter - # Milestone uses :title, Issue uses :name - OpenStruct.new(id: 0, title: 'None (backlog)', name: 'Unassigned') - end - - def url_for_project_issues(project = @project, options = {}) - return '' if project.nil? - - if options[:only_path] - project.issues_tracker.project_path - else - project.issues_tracker.project_url - end - end - - def url_for_new_issue(project = @project, options = {}) - return '' if project.nil? - - if options[:only_path] - project.issues_tracker.new_issue_path - else - project.issues_tracker.new_issue_url - end - end - - def url_for_issue(issue_iid, project = @project, options = {}) - return '' if project.nil? - - if options[:only_path] - project.issues_tracker.issue_path(issue_iid) - else - project.issues_tracker.issue_url(issue_iid) - end - end - - def title_for_issue(issue_iid, project = @project) - return '' if project.nil? - - if project.default_issues_tracker? - issue = project.issues.where(iid: issue_iid).first - return issue.title if issue - end - - '' - end - - def issue_timestamp(issue) - # Shows the created at time and the updated at time if different - ts = "#{time_ago_with_tooltip(issue.created_at, 'bottom', 'note_created_ago')}" - if issue.updated_at != issue.created_at - ts << capture_haml do - haml_tag :span do - haml_concat '·' - haml_concat icon('edit', title: 'edited') - haml_concat time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_edited_ago') - end - end - end - ts.html_safe - end - - def bulk_update_milestone_options - options_for_select([['None (backlog)', -1]]) + - options_from_collection_for_select(project_active_milestones, 'id', - 'title', params[:milestone_id]) - end - - def milestone_options(object) - options_from_collection_for_select(object.project.milestones.active, - 'id', 'title', object.milestone_id) - end - - def issue_box_class(item) - if item.respond_to?(:expired?) && item.expired? - 'issue-box-expired' - elsif item.respond_to?(:merged?) && item.merged? - 'issue-box-merged' - elsif item.closed? - 'issue-box-closed' - else - 'issue-box-open' - end - end - - def issue_to_atom(xml, issue) - xml.entry do - xml.id namespace_project_issue_url(issue.project.namespace, - issue.project, issue) - xml.link href: namespace_project_issue_url(issue.project.namespace, - issue.project, issue) - xml.title truncate(issue.title, length: 80) - xml.updated issue.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, width: "40", height: "40", url: avatar_icon(issue.author_email) - xml.author do |author| - xml.name issue.author_name - xml.email issue.author_email - end - xml.summary issue.title - end - end -end diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb deleted file mode 100644 index 32ef2e7ca8416c7ea3cacb1961370d0bc4092c29..0000000000000000000000000000000000000000 --- a/app/helpers/labels_helper.rb +++ /dev/null @@ -1,54 +0,0 @@ -module LabelsHelper - def project_label_names - @project.labels.pluck(:title) - end - - def render_colored_label(label) - label_color = label.color || Label::DEFAULT_COLOR - text_color = text_color_for_bg(label_color) - - content_tag :span, class: 'label color-label', style: "background-color:#{label_color};color:#{text_color}" do - label.name - end - end - - def suggested_colors - [ - '#0033CC', - '#428BCA', - '#44AD8E', - '#A8D695', - '#5CB85C', - '#69D100', - '#004E00', - '#34495E', - '#7F8C8D', - '#A295D6', - '#5843AD', - '#8E44AD', - '#FFECDB', - '#AD4363', - '#D10069', - '#CC0033', - '#FF0000', - '#D9534F', - '#D1D100', - '#F0AD4E', - '#AD8D43' - ] - end - - def text_color_for_bg(bg_color) - r, g, b = bg_color.slice(1,7).scan(/.{2}/).map(&:hex) - - if (r + g + b) > 500 - "#333" - else - "#FFF" - end - end - - def project_labels_options(project) - options_from_collection_for_select(project.labels, 'name', 'name', params[:label_name]) - end -end diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb deleted file mode 100644 index 54462fd00e3c81687b01226183af68fd5a6acd64..0000000000000000000000000000000000000000 --- a/app/helpers/merge_requests_helper.rb +++ /dev/null @@ -1,52 +0,0 @@ -module MergeRequestsHelper - def new_mr_path_from_push_event(event) - target_project = event.project.forked_from_project || event.project - new_namespace_project_merge_request_path( - event.project.namespace, - event.project, - new_mr_from_push_event(event, target_project) - ) - end - - def new_mr_path_for_fork_from_push_event(event) - new_namespace_project_merge_request_path( - event.project.namespace, - event.project, - new_mr_from_push_event(event, event.project.forked_from_project) - ) - end - - def new_mr_from_push_event(event, target_project) - { - merge_request: { - source_project_id: event.project.id, - target_project_id: target_project.id, - source_branch: event.branch_name, - target_branch: target_project.repository.root_ref - } - } - end - - def mr_css_classes(mr) - classes = "merge-request" - classes << " closed" if mr.closed? - classes << " merged" if mr.merged? - classes - end - - def ci_build_details_path(merge_request) - merge_request.source_project.ci_service.build_page(merge_request.last_commit.sha, merge_request.source_branch) - end - - def merge_path_description(merge_request, separator) - if merge_request.for_fork? - "Project:Branches: #{@merge_request.source_project_path}:#{@merge_request.source_branch} #{separator} #{@merge_request.target_project.path_with_namespace}:#{@merge_request.target_branch}" - else - "Branches: #{@merge_request.source_branch} #{separator} #{@merge_request.target_branch}" - end - end - - def issues_sentence(issues) - issues.map { |i| "##{i.iid}" }.to_sentence - end -end diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb deleted file mode 100644 index 282bdf744d2c74119903873abef25835a55134cf..0000000000000000000000000000000000000000 --- a/app/helpers/milestones_helper.rb +++ /dev/null @@ -1,33 +0,0 @@ -module MilestonesHelper - def milestones_filter_path(opts = {}) - if @project - namespace_project_milestones_path(@project.namespace, @project, opts) - elsif @group - group_milestones_path(@group, opts) - else - dashboard_milestones_path(opts) - end - end - - def milestone_progress_bar(milestone) - options = { - class: 'progress-bar progress-bar-success', - style: "width: #{milestone.percent_complete}%;" - } - - content_tag :div, class: 'progress' do - content_tag :div, nil, options - end - end - - def projects_milestones_options - milestones = - if @project - @project.milestones - else - Milestone.where(project_id: @projects) - end.active - - options_from_collection_for_select(milestones, 'id', 'title', params[:milestone_id]) - end -end diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb deleted file mode 100644 index b3132a1f3ba1e43e289a196793503182a2b5e07e..0000000000000000000000000000000000000000 --- a/app/helpers/namespaces_helper.rb +++ /dev/null @@ -1,36 +0,0 @@ -module NamespacesHelper - def namespaces_options(selected = :current_user, scope = :default) - groups = current_user.owned_groups + current_user.masters_groups - users = [current_user.namespace] - - group_opts = ["Groups", groups.sort_by(&:human_name).map {|g| [g.human_name, g.id]} ] - users_opts = [ "Users", users.sort_by(&:human_name).map {|u| [u.human_name, u.id]} ] - - options = [] - options << group_opts - options << users_opts - - if selected == :current_user && current_user.namespace - selected = current_user.namespace.id - end - - grouped_options_for_select(options, selected) - end - - def namespace_select_tag(id, opts = {}) - css_class = "ajax-namespace-select " - css_class << "multiselect " if opts[:multiple] - css_class << (opts[:class] || '') - value = opts[:selected] || '' - - hidden_field_tag(id, value, class: css_class) - end - - def namespace_icon(namespace, size = 40) - if namespace.kind_of?(Group) - group_icon(namespace) - else - avatar_icon(namespace.owner.email, size) - end - end -end diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb deleted file mode 100644 index 2b03269800ec0091bf806d84aec751a30b12e044..0000000000000000000000000000000000000000 --- a/app/helpers/nav_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -module NavHelper - def nav_menu_collapsed? - cookies[:collapsed_nav] == 'true' - end -end diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb deleted file mode 100644 index ab44fa6ee4300aecda8bc3a2cb5d80b67bac0615..0000000000000000000000000000000000000000 --- a/app/helpers/notes_helper.rb +++ /dev/null @@ -1,85 +0,0 @@ -module NotesHelper - # Helps to distinguish e.g. commit notes in mr notes list - def note_for_main_target?(note) - (@noteable.class.name == note.noteable_type && !note.for_diff_line?) - end - - def note_target_fields(note) - hidden_field_tag(:target_type, note.noteable.class.name.underscore) + - hidden_field_tag(:target_id, note.noteable.id) - end - - def link_to_commit_diff_line_note(note) - if note.for_commit_diff_line? - link_to( - "#{note.diff_file_name}:L#{note.diff_new_line}", - namespace_project_commit_path(@project.namespace, @project, - note.noteable, anchor: note.line_code) - ) - end - end - - def note_timestamp(note) - # Shows the created at time and the updated at time if different - ts = "#{time_ago_with_tooltip(note.created_at, 'bottom', 'note_created_ago')}" - if note.updated_at != note.created_at - ts << capture_haml do - haml_tag :span do - haml_concat '·' - haml_concat icon('edit', title: 'edited') - haml_concat time_ago_with_tooltip(note.updated_at, 'bottom', 'note_edited_ago') - end - end - end - ts.html_safe - end - - def noteable_json(noteable) - { - id: noteable.id, - class: noteable.class.name, - resources: noteable.class.table_name, - project_id: noteable.project.id, - }.to_json - end - - def link_to_new_diff_note(line_code) - discussion_id = Note.build_discussion_id( - @comments_target[:noteable_type], - @comments_target[:noteable_id] || @comments_target[:commit_id], - line_code - ) - - data = { - noteable_type: @comments_target[:noteable_type], - noteable_id: @comments_target[:noteable_id], - commit_id: @comments_target[:commit_id], - line_code: line_code, - discussion_id: discussion_id - } - - button_tag(class: 'btn add-diff-note js-add-diff-note-button', - data: data, - title: 'Add a comment to this line') do - icon('comment-o') - end - end - - def link_to_reply_diff(note) - return unless current_user - - data = { - noteable_type: note.noteable_type, - noteable_id: note.noteable_id, - commit_id: note.commit_id, - line_code: note.line_code, - discussion_id: note.discussion_id - } - - button_tag class: 'btn reply-btn js-discussion-reply-button', - data: data, title: 'Add a reply' do - link_text = icon('comment') - link_text << ' Reply' - end - end -end diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb deleted file mode 100644 index f771fe761efc19e9adb674845c2a2b3fe7edbf1e..0000000000000000000000000000000000000000 --- a/app/helpers/notifications_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module NotificationsHelper - def notification_icon(notification) - if notification.disabled? - icon('volume-off', class: 'ns-mute') - elsif notification.participating? - icon('volume-down', class: 'ns-part') - elsif notification.watch? - icon('volume-up', class: 'ns-watch') - else - icon('circle-o', class: 'ns-default') - end - end -end diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb deleted file mode 100644 index 997b91de07764368c19d530942160685d8fb7dd0..0000000000000000000000000000000000000000 --- a/app/helpers/oauth_helper.rb +++ /dev/null @@ -1,34 +0,0 @@ -module OauthHelper - def ldap_enabled? - Gitlab.config.ldap.enabled - end - - def default_providers - [:twitter, :github, :gitlab, :bitbucket, :google_oauth2, :ldap] - end - - def enabled_oauth_providers - Devise.omniauth_providers - end - - def enabled_social_providers - enabled_oauth_providers.select do |name| - [:twitter, :gitlab, :github, :bitbucket, :google_oauth2].include?(name.to_sym) - end - end - - def additional_providers - enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')} - end - - def oauth_image_tag(provider, size = 64) - file_name = "#{provider.to_s.split('_').first}_#{size}.png" - image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}") - end - - def oauth_active?(provider) - current_user.identities.exists?(provider: provider.to_s) - end - - extend self -end diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb deleted file mode 100644 index 780c7cd51332193bb526402232fd36ad26d6cb7c..0000000000000000000000000000000000000000 --- a/app/helpers/profile_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module ProfileHelper - def show_profile_username_tab? - current_user.can_change_username? - end - - def show_profile_social_tab? - enabled_social_providers.any? - end - - def show_profile_remove_tab? - signup_enabled? - end -end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb deleted file mode 100644 index c2a7732e6f03dddcc2e2601dc17127088eedbad4..0000000000000000000000000000000000000000 --- a/app/helpers/projects_helper.rb +++ /dev/null @@ -1,329 +0,0 @@ -module ProjectsHelper - def remove_from_project_team_message(project, member) - if member.user - "You are going to remove #{member.user.name} from #{project.name} project team. Are you sure?" - else - "You are going to revoke the invitation for #{member.invite_email} to join #{project.name} project team. Are you sure?" - end - end - - def link_to_project(project) - link_to [project.namespace.becomes(Namespace), project] do - title = content_tag(:span, project.name, class: 'project-name') - - if project.namespace - namespace = content_tag(:span, "#{project.namespace.human_name} / ", class: 'namespace-name') - title = namespace + title - end - - title - end - end - - def link_to_member(project, author, opts = {}) - default_opts = { avatar: true, name: true, size: 16 } - opts = default_opts.merge(opts) - - return "(deleted)" unless author - - author_html = "" - - # Build avatar image tag - author_html << image_tag(avatar_icon(author.try(:email), opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar] - - # Build name span tag - author_html << content_tag(:span, sanitize(author.name), class: 'author') if opts[:name] - - author_html = author_html.html_safe - - if opts[:name] - link_to(author_html, user_path(author), class: "author_link").html_safe - else - link_to(author_html, user_path(author), class: "author_link has_tooltip", data: { :'original-title' => sanitize(author.name) } ).html_safe - end - end - - def project_title(project) - if project.group - content_tag :span do - link_to( - simple_sanitize(project.group.name), group_path(project.group) - ) + ' / ' + - link_to(simple_sanitize(project.name), - project_path(project)) - end - else - owner = project.namespace.owner - content_tag :span do - link_to( - simple_sanitize(owner.name), user_path(owner) - ) + ' / ' + - link_to(simple_sanitize(project.name), - project_path(project)) - end - end - end - - def remove_project_message(project) - "You are going to remove #{project.name_with_namespace}.\n Removed project CANNOT be restored!\n Are you ABSOLUTELY sure?" - end - - def transfer_project_message(project) - "You are going to transfer #{project.name_with_namespace} to another owner. Are you ABSOLUTELY sure?" - end - - def project_nav_tabs - @nav_tabs ||= get_project_nav_tabs(@project, current_user) - end - - def project_nav_tab?(name) - project_nav_tabs.include? name - end - - def project_active_milestones - @project.milestones.active.order("due_date, title ASC") - end - - def link_to_toggle_star(title, starred) - cls = 'star-btn btn btn-sm btn-default' - - toggle_text = - if starred - ' Unstar' - else - ' Star' - end - - toggle_html = content_tag('span', class: 'toggle') do - icon('star') + toggle_text - end - - count_html = content_tag('span', class: 'count') do - @project.star_count.to_s - end - - link_opts = { - title: title, - class: cls, - method: :post, - remote: true, - data: { type: 'json' } - } - - path = toggle_star_namespace_project_path(@project.namespace, @project) - - content_tag 'span', class: starred ? 'turn-on' : 'turn-off' do - link_to(path, link_opts) do - toggle_html + ' ' + count_html - end - end - end - - def link_to_toggle_fork - html = content_tag('span') do - icon('code-fork') + ' Fork' - end - - count_html = content_tag(:span, class: 'count') do - @project.forks_count.to_s - end - - html + count_html - end - - def project_for_deploy_key(deploy_key) - if deploy_key.projects.include?(@project) - @project - else - deploy_key.projects.find { |project| can?(current_user, :read_project, project) } - end - end - - private - - def get_project_nav_tabs(project, current_user) - nav_tabs = [:home] - - if !project.empty_repo? && can?(current_user, :download_code, project) - nav_tabs << [:files, :commits, :network, :graphs] - end - - if project.repo_exists? && project.merge_requests_enabled - nav_tabs << :merge_requests - end - - if can?(current_user, :admin_project, project) - nav_tabs << :settings - end - - [:issues, :wiki, :snippets].each do |feature| - nav_tabs << feature if project.send :"#{feature}_enabled" - end - - if project.issues_enabled || project.merge_requests_enabled - nav_tabs << [:milestones, :labels] - end - - nav_tabs.flatten - end - - def git_user_name - if current_user - current_user.name - else - "Your name" - end - end - - def git_user_email - if current_user - current_user.email - else - "your@email.com" - end - end - - def repository_size(project = nil) - "#{(project || @project).repository_size} MB" - rescue - # In order to prevent 500 error - # when application cannot allocate memory - # to calculate repo size - just show 'Unknown' - 'unknown' - end - - def project_head_title - title = @project.name_with_namespace - - title = if current_controller?(:tree) - "#{@project.path}\/#{@path} at #{@ref} - " + title - elsif current_controller?(:issues) - if current_action?(:show) - "Issue ##{@issue.iid} - #{@issue.title} - " + title - else - "Issues - " + title - end - elsif current_controller?(:blob) - if current_action?(:new) || current_action?(:create) - "New file at #{@ref}" - elsif current_action?(:show) - "#{@blob.path} at #{@ref}" - elsif @blob - "Edit file #{@blob.path} at #{@ref}" - end - elsif current_controller?(:commits) - "Commits at #{@ref} - " + title - elsif current_controller?(:merge_requests) - if current_action?(:show) - "Merge request ##{@merge_request.iid} - " + title - else - "Merge requests - " + title - end - elsif current_controller?(:wikis) - "Wiki - " + title - elsif current_controller?(:network) - "Network graph - " + title - elsif current_controller?(:graphs) - "Graphs - " + title - else - title - end - - title - end - - def default_url_to_repo(project = nil) - project = project || @project - current_user ? project.url_to_repo : project.http_url_to_repo - end - - def default_clone_protocol - current_user ? "ssh" : "http" - end - - def project_last_activity(project) - if project.last_activity_at - time_ago_with_tooltip(project.last_activity_at, 'bottom', 'last_activity_time_ago') - else - "Never" - end - end - - def contribution_guide_url(project) - if project && contribution_guide = project.repository.contribution_guide - namespace_project_blob_path( - project.namespace, - project, - tree_join(project.default_branch, - contribution_guide.name) - ) - end - end - - def changelog_url(project) - if project && changelog = project.repository.changelog - namespace_project_blob_path( - project.namespace, - project, - tree_join(project.default_branch, - changelog.name) - ) - end - end - - def license_url(project) - if project && license = project.repository.license - namespace_project_blob_path( - project.namespace, - project, - tree_join(project.default_branch, - license.name) - ) - end - end - - def version_url(project) - if project && version = project.repository.version - namespace_project_blob_path( - project.namespace, - project, - tree_join(project.default_branch, - version.name) - ) - end - end - - def hidden_pass_url(original_url) - result = URI(original_url) - result.password = '*****' unless result.password.nil? - result - rescue - original_url - end - - def project_wiki_path_with_version(proj, page, version, is_newest) - url_params = is_newest ? {} : { version_id: version } - namespace_project_wiki_path(proj.namespace, proj, page, url_params) - end - - def project_status_css_class(status) - case status - when "started" - "active" - when "failed" - "danger" - when "finished" - "success" - end - end - - def service_field_value(type, value) - return value unless type == 'password' - - if value.present? - "***********" - else - nil - end - end -end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb deleted file mode 100644 index c31a556ff7b3d83a0ab6663713eb0d21b98b3893..0000000000000000000000000000000000000000 --- a/app/helpers/search_helper.rb +++ /dev/null @@ -1,112 +0,0 @@ -module SearchHelper - def search_autocomplete_opts(term) - return unless current_user - - resources_results = [ - groups_autocomplete(term), - projects_autocomplete(term) - ].flatten - - generic_results = project_autocomplete + default_autocomplete + help_autocomplete - generic_results.select! { |result| result[:label] =~ Regexp.new(term, "i") } - - [ - resources_results, - generic_results - ].flatten.uniq do |item| - item[:label] - end - end - - private - - # Autocomplete results for various settings pages - def default_autocomplete - [ - { label: "Profile settings", url: profile_path }, - { label: "SSH Keys", url: profile_keys_path }, - { label: "Dashboard", url: root_path }, - { label: "Admin Section", url: admin_root_path }, - ] - end - - # Autocomplete results for internal help pages - def help_autocomplete - [ - { label: "help: API Help", url: help_page_path("api", "README") }, - { label: "help: Markdown Help", url: help_page_path("markdown", "markdown") }, - { label: "help: Permissions Help", url: help_page_path("permissions", "permissions") }, - { label: "help: Public Access Help", url: help_page_path("public_access", "public_access") }, - { label: "help: Rake Tasks Help", url: help_page_path("raketasks", "README") }, - { label: "help: SSH Keys Help", url: help_page_path("ssh", "README") }, - { label: "help: System Hooks Help", url: help_page_path("system_hooks", "system_hooks") }, - { label: "help: Web Hooks Help", url: help_page_path("web_hooks", "web_hooks") }, - { label: "help: Workflow Help", url: help_page_path("workflow", "README") }, - ] - end - - # Autocomplete results for the current project, if it's defined - def project_autocomplete - if @project && @project.repository.exists? && @project.repository.root_ref - prefix = search_result_sanitize(@project.name_with_namespace) - ref = @ref || @project.repository.root_ref - - [ - { label: "#{prefix} - Files", url: namespace_project_tree_path(@project.namespace, @project, ref) }, - { label: "#{prefix} - Commits", url: namespace_project_commits_path(@project.namespace, @project, ref) }, - { label: "#{prefix} - Network", url: namespace_project_network_path(@project.namespace, @project, ref) }, - { label: "#{prefix} - Graph", url: namespace_project_graph_path(@project.namespace, @project, ref) }, - { label: "#{prefix} - Issues", url: namespace_project_issues_path(@project.namespace, @project) }, - { label: "#{prefix} - Merge Requests", url: namespace_project_merge_requests_path(@project.namespace, @project) }, - { label: "#{prefix} - Milestones", url: namespace_project_milestones_path(@project.namespace, @project) }, - { label: "#{prefix} - Snippets", url: namespace_project_snippets_path(@project.namespace, @project) }, - { label: "#{prefix} - Members", url: namespace_project_project_members_path(@project.namespace, @project) }, - { label: "#{prefix} - Wiki", url: namespace_project_wikis_path(@project.namespace, @project) }, - ] - else - [] - end - end - - # Autocomplete results for the current user's groups - def groups_autocomplete(term, limit = 5) - current_user.authorized_groups.search(term).limit(limit).map do |group| - { - label: "group: #{search_result_sanitize(group.name)}", - url: group_path(group) - } - end - end - - # Autocomplete results for the current user's projects - def projects_autocomplete(term, limit = 5) - ProjectsFinder.new.execute(current_user).search_by_title(term). - sorted_by_stars.non_archived.limit(limit).map do |p| - { - label: "project: #{search_result_sanitize(p.name_with_namespace)}", - url: namespace_project_path(p.namespace, p) - } - end - end - - def search_result_sanitize(str) - Sanitize.clean(str) - end - - def search_filter_path(options={}) - exist_opts = { - search: params[:search], - project_id: params[:project_id], - group_id: params[:group_id], - scope: params[:scope] - } - - options = exist_opts.merge(options) - search_path(options) - end - - # Sanitize html generated after parsing markdown from issue description or comment - def search_md_sanitize(html) - sanitize(html, tags: %w(a p ol ul li pre code)) - end -end diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb deleted file mode 100644 index bec8f2f1aa763d419ca9a46418a30de2089385e2..0000000000000000000000000000000000000000 --- a/app/helpers/selects_helper.rb +++ /dev/null @@ -1,42 +0,0 @@ -module SelectsHelper - def users_select_tag(id, opts = {}) - css_class = "ajax-users-select " - css_class << "multiselect " if opts[:multiple] - css_class << (opts[:class] || '') - value = opts[:selected] || '' - placeholder = opts[:placeholder] || 'Search for a user' - - null_user = opts[:null_user] || false - any_user = opts[:any_user] || false - email_user = opts[:email_user] || false - first_user = opts[:first_user] && current_user ? current_user.username : false - - html = { - class: css_class, - 'data-placeholder' => placeholder, - 'data-null-user' => null_user, - 'data-any-user' => any_user, - 'data-email-user' => email_user, - 'data-first-user' => first_user - } - - unless opts[:scope] == :all - if @project - html['data-project-id'] = @project.id - elsif @group - html['data-group-id'] = @group.id - end - end - - hidden_field_tag(id, value, html) - end - - def groups_select_tag(id, opts = {}) - css_class = "ajax-groups-select " - css_class << "multiselect " if opts[:multiple] - css_class << (opts[:class] || '') - value = opts[:selected] || '' - - hidden_field_tag(id, value, class: css_class) - end -end diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb deleted file mode 100644 index 906cb12cd48f911c0e1fde91be1a577315c682e7..0000000000000000000000000000000000000000 --- a/app/helpers/snippets_helper.rb +++ /dev/null @@ -1,20 +0,0 @@ -module SnippetsHelper - def lifetime_select_options - options = [ - ['forever', nil], - ['1 day', "#{Date.current + 1.day}"], - ['1 week', "#{Date.current + 1.week}"], - ['1 month', "#{Date.current + 1.month}"] - ] - options_for_select(options) - end - - def reliable_snippet_path(snippet) - if snippet.project_id? - namespace_project_snippet_path(snippet.project.namespace, - snippet.project, snippet) - else - snippet_path(snippet) - end - end -end diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb deleted file mode 100644 index bb12d43f3972c040a4b8e21df990e71768f68c5e..0000000000000000000000000000000000000000 --- a/app/helpers/sorting_helper.rb +++ /dev/null @@ -1,96 +0,0 @@ -module SortingHelper - def sort_options_hash - { - sort_value_name => sort_title_name, - sort_value_recently_updated => sort_title_recently_updated, - sort_value_oldest_updated => sort_title_oldest_updated, - sort_value_recently_created => sort_title_recently_created, - sort_value_oldest_created => sort_title_oldest_created, - sort_value_milestone_soon => sort_title_milestone_soon, - sort_value_milestone_later => sort_title_milestone_later, - sort_value_largest_repo => sort_title_largest_repo, - sort_value_recently_signin => sort_title_recently_signin, - sort_value_oldest_signin => sort_title_oldest_signin, - } - end - - def sort_title_oldest_updated - 'Oldest updated' - end - - def sort_title_recently_updated - 'Recently updated' - end - - def sort_title_oldest_created - 'Oldest created' - end - - def sort_title_recently_created - 'Recently created' - end - - def sort_title_milestone_soon - 'Milestone due soon' - end - - def sort_title_milestone_later - 'Milestone due later' - end - - def sort_title_name - 'Name' - end - - def sort_title_largest_repo - 'Largest repository' - end - - def sort_title_recently_signin - 'Recent sign in' - end - - def sort_title_oldest_signin - 'Oldest sign in' - end - - def sort_value_oldest_updated - 'updated_asc' - end - - def sort_value_recently_updated - 'updated_desc' - end - - def sort_value_oldest_created - 'created_asc' - end - - def sort_value_recently_created - 'created_desc' - end - - def sort_value_milestone_soon - 'milestone_due_asc' - end - - def sort_value_milestone_later - 'milestone_due_desc' - end - - def sort_value_name - 'name_asc' - end - - def sort_value_largest_repo - 'repository_size_desc' - end - - def sort_value_recently_signin - 'recent_sign_in' - end - - def sort_value_oldest_signin - 'oldest_sign_in' - end -end diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb deleted file mode 100644 index 9954617c76295c56662fbe8a0361a5612984e5e5..0000000000000000000000000000000000000000 --- a/app/helpers/submodule_helper.rb +++ /dev/null @@ -1,74 +0,0 @@ -module SubmoduleHelper - include Gitlab::ShellAdapter - - # links to files listing for submodule if submodule is a project on this server - def submodule_links(submodule_item, ref = nil) - url = @repository.submodule_url_for(ref, submodule_item.path) - - return url, nil unless url =~ /([^\/:]+)\/([^\/]+\.git)\Z/ - - namespace = $1 - project = $2 - project.chomp!('.git') - - if self_url?(url, namespace, project) - return namespace_project_path(namespace, project), - namespace_project_tree_path(namespace, project, - submodule_item.id) - elsif relative_self_url?(url) - relative_self_links(url, submodule_item.id) - elsif github_dot_com_url?(url) - standard_links('github.com', namespace, project, submodule_item.id) - elsif gitlab_dot_com_url?(url) - standard_links('gitlab.com', namespace, project, submodule_item.id) - else - return url, nil - end - end - - protected - - def github_dot_com_url?(url) - url =~ /github\.com[\/:][^\/]+\/[^\/]+\Z/ - end - - def gitlab_dot_com_url?(url) - url =~ /gitlab\.com[\/:][^\/]+\/[^\/]+\Z/ - end - - def self_url?(url, namespace, project) - return true if url == [ Gitlab.config.gitlab.url, '/', namespace, '/', - project, '.git' ].join('') - url == gitlab_shell.url_to_repo([namespace, '/', project].join('')) - end - - def relative_self_url?(url) - # (./)?(../repo.git) || (./)?(../../project/repo.git) ) - url =~ /\A((\.\/)?(\.\.\/))(?!(\.\.)|(.*\/)).*\.git\z/ || url =~ /\A((\.\/)?(\.\.\/){2})(?!(\.\.))([^\/]*)\/(?!(\.\.)|(.*\/)).*\.git\z/ - end - - def standard_links(host, namespace, project, commit) - base = [ 'https://', host, '/', namespace, '/', project ].join('') - [base, [ base, '/tree/', commit ].join('')] - end - - def relative_self_links(url, commit) - # Map relative links to a namespace and project - # For example: - # ../bar.git -> same namespace, repo bar - # ../foo/bar.git -> namespace foo, repo bar - # ../../foo/bar/baz.git -> namespace bar, repo baz - components = url.split('/') - base = components.pop.gsub(/.git$/, '') - namespace = components.pop.gsub(/^\.\.$/, '') - - if namespace.empty? - namespace = @project.group.path - end - - [ - namespace_project_path(namespace, base), - namespace_project_tree_path(namespace, base, commit) - ] - end -end diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb deleted file mode 100644 index a1d263d9d3a92369fa5083e4d33290923b21ac94..0000000000000000000000000000000000000000 --- a/app/helpers/tab_helper.rb +++ /dev/null @@ -1,123 +0,0 @@ -module TabHelper - # Navigation link helper - # - # Returns an `li` element with an 'active' class if the supplied - # controller(s) and/or action(s) are currently active. The content of the - # element is the value passed to the block. - # - # options - The options hash used to determine if the element is "active" (default: {}) - # :controller - One or more controller names to check (optional). - # :action - One or more action names to check (optional). - # :path - A shorthand path, such as 'dashboard#index', to check (optional). - # :html_options - Extra options to be passed to the list element (optional). - # block - An optional block that will become the contents of the returned - # `li` element. - # - # When both :controller and :action are specified, BOTH must match in order - # to be marked as active. When only one is given, either can match. - # - # Examples - # - # # Assuming we're on TreeController#show - # - # # Controller matches, but action doesn't - # nav_link(controller: [:tree, :refs], action: :edit) { "Hello" } - # # => '
  • Hello
  • ' - # - # # Controller matches - # nav_link(controller: [:tree, :refs]) { "Hello" } - # # => '
  • Hello
  • ' - # - # # Several paths - # nav_link(path: ['tree#show', 'profile#show']) { "Hello" } - # # => '
  • Hello
  • ' - # - # # Shorthand path - # nav_link(path: 'tree#show') { "Hello" } - # # => '
  • Hello
  • ' - # - # # Supplying custom options for the list element - # nav_link(controller: :tree, html_options: {class: 'home'}) { "Hello" } - # # => '
  • Hello
  • ' - # - # Returns a list item element String - def nav_link(options = {}, &block) - klass = active_nav_link?(options) ? 'active' : '' - - # Add our custom class into the html_options, which may or may not exist - # and which may or may not already have a :class key - o = options.delete(:html_options) || {} - o[:class] ||= '' - o[:class] += ' ' + klass - o[:class].strip! - - if block_given? - content_tag(:li, capture(&block), o) - else - content_tag(:li, nil, o) - end - end - - def active_nav_link?(options) - if path = options.delete(:path) - unless path.respond_to?(:each) - path = [path] - end - - path.any? do |single_path| - current_path?(single_path) - end - else - c = options.delete(:controller) - a = options.delete(:action) - - if c && a - # When given both options, make sure BOTH are true - current_controller?(*c) && current_action?(*a) - else - # Otherwise check EITHER option - current_controller?(*c) || current_action?(*a) - end - end - end - - def current_path?(path) - c, a, _ = path.split('#') - current_controller?(c) && current_action?(a) - end - - def project_tab_class - return "active" if current_page?(controller: "/projects", action: :edit, id: @project) - - if ['services', 'hooks', 'deploy_keys', 'project_members', 'protected_branches'].include? controller.controller_name - "active" - end - end - - def branches_tab_class - if current_controller?(:protected_branches) || - current_controller?(:branches) || - current_page?(namespace_project_repository_path(@project.namespace, - @project)) - 'active' - end - end - - # Use nav_tab for save controller/action but different params - def nav_tab(key, value, &block) - o = {} - o[:class] = "" - - if value.nil? - o[:class] << " active" if params[key].blank? - else - o[:class] << " active" if params[key] == value - end - - if block_given? - content_tag(:li, capture(&block), o) - else - content_tag(:li, nil, o) - end - end -end diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb deleted file mode 100644 index fb85544df2d7a9da130de651631bf962562cfd6a..0000000000000000000000000000000000000000 --- a/app/helpers/tags_helper.rb +++ /dev/null @@ -1,14 +0,0 @@ -module TagsHelper - def tag_path(tag) - "/tags/#{tag}" - end - - def tag_list(project) - html = '' - project.tag_list.each do |tag| - html << link_to(tag, tag_path(tag)) - end - - html.html_safe - end -end diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb deleted file mode 100644 index 6dd9b6f017cc909f3f125ec31b7b97dc12db0944..0000000000000000000000000000000000000000 --- a/app/helpers/tree_helper.rb +++ /dev/null @@ -1,94 +0,0 @@ -module TreeHelper - # Sorts a repository's tree so that folders are before files and renders - # their corresponding partials - # - # contents - A Grit::Tree object for the current tree - def render_tree(tree) - # Render Folders before Files/Submodules - folders, files, submodules = tree.trees, tree.blobs, tree.submodules - - tree = "" - - # Render folders if we have any - tree << render(partial: 'projects/tree/tree_item', collection: folders, - locals: { type: 'folder' }) if folders.present? - - # Render files if we have any - tree << render(partial: 'projects/tree/blob_item', collection: files, - locals: { type: 'file' }) if files.present? - - # Render submodules if we have any - tree << render(partial: 'projects/tree/submodule_item', - collection: submodules) if submodules.present? - - tree.html_safe - end - - def render_readme(readme) - if gitlab_markdown?(readme.name) - preserve(markdown(readme.data)) - elsif markup?(readme.name) - render_markup(readme.name, readme.data) - else - simple_format(readme.data) - end - end - - # Return an image icon depending on the file type and mode - # - # type - String type of the tree item; either 'folder' or 'file' - # mode - File unix mode - # name - File name - def tree_icon(type, mode, name) - icon("#{file_type_icon_class(type, mode, name)} fw") - end - - def tree_hex_class(content) - "file_#{hexdigest(content.name)}" - end - - # Simple shortcut to File.join - def tree_join(*args) - File.join(*args) - end - - def allowed_tree_edit?(project = nil, ref = nil) - project ||= @project - ref ||= @ref - return false unless project.repository.branch_names.include?(ref) - - ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref) - end - - def tree_breadcrumbs(tree, max_links = 2) - if @path.present? - part_path = "" - parts = @path.split('/') - - yield('..', nil) if parts.count > max_links - - parts.each do |part| - part_path = File.join(part_path, part) unless part_path.empty? - part_path = part if part_path.empty? - - next unless parts.last(2).include?(part) if parts.count > max_links - yield(part, tree_join(@ref, part_path)) - end - end - end - - def up_dir_path - file = File.join(@path, "..") - tree_join(@ref, file) - end - - # returns the relative path of the first subdir that doesn't have only one directory descendant - def flatten_tree(tree) - subtree = Gitlab::Git::Tree.where(@repository, @commit.id, tree.path) - if subtree.count == 1 && subtree.first.dir? - return tree_join(tree.name, flatten_tree(subtree.first)) - else - return tree.name - end - end -end diff --git a/app/helpers/visibility_level_helper.rb b/app/helpers/visibility_level_helper.rb deleted file mode 100644 index 0d573e72a80aa93807d869b1436b5fdd070eda13..0000000000000000000000000000000000000000 --- a/app/helpers/visibility_level_helper.rb +++ /dev/null @@ -1,67 +0,0 @@ -module VisibilityLevelHelper - def visibility_level_color(level) - case level - when Gitlab::VisibilityLevel::PRIVATE - 'vs-private' - when Gitlab::VisibilityLevel::INTERNAL - 'vs-internal' - when Gitlab::VisibilityLevel::PUBLIC - 'vs-public' - end - end - - def visibility_level_description(level) - capture_haml do - haml_tag :span do - case level - when Gitlab::VisibilityLevel::PRIVATE - haml_concat "Project access must be granted explicitly for each user." - when Gitlab::VisibilityLevel::INTERNAL - haml_concat "The project can be cloned by" - haml_concat "any logged in user." - when Gitlab::VisibilityLevel::PUBLIC - haml_concat "The project can be cloned" - haml_concat "without any" - haml_concat "authentication." - end - end - end - end - - def snippet_visibility_level_description(level) - capture_haml do - haml_tag :span do - case level - when Gitlab::VisibilityLevel::PRIVATE - haml_concat "The snippet is visible only for me" - when Gitlab::VisibilityLevel::INTERNAL - haml_concat "The snippet is visible for any logged in user." - when Gitlab::VisibilityLevel::PUBLIC - haml_concat "The snippet can be accessed" - haml_concat "without any" - haml_concat "authentication." - end - end - end - end - - def visibility_level_icon(level) - case level - when Gitlab::VisibilityLevel::PRIVATE - private_icon - when Gitlab::VisibilityLevel::INTERNAL - internal_icon - when Gitlab::VisibilityLevel::PUBLIC - public_icon - end - end - - def visibility_level_label(level) - Project.visibility_levels.key(level) - end - - def restricted_visibility_levels(show_all = false) - return [] if current_user.is_admin? && !show_all - current_application_settings.restricted_visibility_levels || [] - end -end diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb deleted file mode 100644 index a3bc64c010e0a5dbd1c457e65a445c0530e08352..0000000000000000000000000000000000000000 --- a/app/helpers/wiki_helper.rb +++ /dev/null @@ -1,22 +0,0 @@ -module WikiHelper - # Rails v4.1.9+ escapes all model IDs, converting slashes into %2F. The - # only way around this is to implement our own path generators. - def namespace_project_wiki_path(namespace, project, wiki_page, *args) - slug = - case wiki_page - when Symbol - wiki_page - else - wiki_page.slug - end - namespace_project_path(namespace, project) + "/wikis/#{slug}" - end - - def edit_namespace_project_wiki_path(namespace, project, wiki_page, *args) - namespace_project_wiki_path(namespace, project, wiki_page) + '/edit' - end - - def history_namespace_project_wiki_path(namespace, project, wiki_page, *args) - namespace_project_wiki_path(namespace, project, wiki_page) + '/history' - end -end diff --git a/app/mailers/.gitkeep b/app/mailers/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/app/mailers/emails/groups.rb b/app/mailers/emails/groups.rb deleted file mode 100644 index 1c43f95dc8c61529b0ea4c18fadf91692f0d3575..0000000000000000000000000000000000000000 --- a/app/mailers/emails/groups.rb +++ /dev/null @@ -1,52 +0,0 @@ -module Emails - module Groups - def group_access_granted_email(group_member_id) - @group_member = GroupMember.find(group_member_id) - @group = @group_member.group - - @target_url = group_url(@group) - @current_user = @group_member.user - - mail(to: @group_member.user.notification_email, - subject: subject("Access to group was granted")) - end - - def group_member_invited_email(group_member_id, token) - @group_member = GroupMember.find group_member_id - @group = @group_member.group - @token = token - - @target_url = group_url(@group) - @current_user = @group_member.user - - mail(to: @group_member.invite_email, - subject: "Invitation to join group #{@group.name}") - end - - def group_invite_accepted_email(group_member_id) - @group_member = GroupMember.find group_member_id - return if @group_member.created_by.nil? - - @group = @group_member.group - - @target_url = group_url(@group) - @current_user = @group_member.created_by - - mail(to: @group_member.created_by.notification_email, - subject: subject("Invitation accepted")) - end - - def group_invite_declined_email(group_id, invite_email, access_level, created_by_id) - return if created_by_id.nil? - - @group = Group.find(group_id) - @current_user = @created_by = User.find(created_by_id) - @access_level = access_level - @invite_email = invite_email - - @target_url = group_url(@group) - mail(to: @created_by.notification_email, - subject: subject("Invitation declined")) - end - end -end diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb deleted file mode 100644 index 687bac3aa31a009de8219bf58624626bee70c60b..0000000000000000000000000000000000000000 --- a/app/mailers/emails/issues.rb +++ /dev/null @@ -1,47 +0,0 @@ -module Emails - module Issues - def new_issue_email(recipient_id, issue_id) - @issue = Issue.find(issue_id) - @project = @issue.project - @target_url = namespace_project_issue_url(@project.namespace, @project, @issue) - mail_new_thread(@issue, - from: sender(@issue.author_id), - to: recipient(recipient_id), - subject: subject("#{@issue.title} (##{@issue.iid})")) - end - - def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id, updated_by_user_id) - @issue = Issue.find(issue_id) - @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id - @project = @issue.project - @target_url = namespace_project_issue_url(@project.namespace, @project, @issue) - mail_answer_thread(@issue, - from: sender(updated_by_user_id), - to: recipient(recipient_id), - subject: subject("#{@issue.title} (##{@issue.iid})")) - end - - def closed_issue_email(recipient_id, issue_id, updated_by_user_id) - @issue = Issue.find issue_id - @project = @issue.project - @updated_by = User.find updated_by_user_id - @target_url = namespace_project_issue_url(@project.namespace, @project, @issue) - mail_answer_thread(@issue, - from: sender(updated_by_user_id), - to: recipient(recipient_id), - subject: subject("#{@issue.title} (##{@issue.iid})")) - end - - def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id) - @issue = Issue.find issue_id - @issue_status = status - @project = @issue.project - @updated_by = User.find updated_by_user_id - @target_url = namespace_project_issue_url(@project.namespace, @project, @issue) - mail_answer_thread(@issue, - from: sender(updated_by_user_id), - to: recipient(recipient_id), - subject: subject("#{@issue.title} (##{@issue.iid})")) - end - end -end diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb deleted file mode 100644 index 512a8f7ea6be5034077a1944b066415c61a66b0d..0000000000000000000000000000000000000000 --- a/app/mailers/emails/merge_requests.rb +++ /dev/null @@ -1,109 +0,0 @@ -module Emails - module MergeRequests - def new_merge_request_email(recipient_id, merge_request_id) - @merge_request = MergeRequest.find(merge_request_id) - @project = @merge_request.project - @target_url = namespace_project_merge_request_url(@project.namespace, - @project, - @merge_request) - mail_new_thread(@merge_request, - from: sender(@merge_request.author_id), - to: recipient(recipient_id), - subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) - end - - def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, updated_by_user_id) - @merge_request = MergeRequest.find(merge_request_id) - @previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id - @project = @merge_request.project - @target_url = namespace_project_merge_request_url(@project.namespace, - @project, - @merge_request) - mail_answer_thread(@merge_request, - from: sender(updated_by_user_id), - to: recipient(recipient_id), - subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) - end - - def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) - @merge_request = MergeRequest.find(merge_request_id) - @updated_by = User.find updated_by_user_id - @project = @merge_request.project - @target_url = namespace_project_merge_request_url(@project.namespace, - @project, - @merge_request) - mail_answer_thread(@merge_request, - from: sender(updated_by_user_id), - to: recipient(recipient_id), - subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) - end - - def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) - @merge_request = MergeRequest.find(merge_request_id) - @project = @merge_request.project - @target_url = namespace_project_merge_request_url(@project.namespace, - @project, - @merge_request) - mail_answer_thread(@merge_request, - from: sender(updated_by_user_id), - to: recipient(recipient_id), - subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) - end - - def merge_request_status_email(recipient_id, merge_request_id, status, updated_by_user_id) - @merge_request = MergeRequest.find(merge_request_id) - @mr_status = status - @project = @merge_request.project - @updated_by = User.find updated_by_user_id - @target_url = namespace_project_merge_request_url(@project.namespace, - @project, - @merge_request) - set_reference("merge_request_#{merge_request_id}") - mail_answer_thread(@merge_request, - from: sender(updated_by_user_id), - to: recipient(recipient_id), - subject: subject("#{@merge_request.title} (##{@merge_request.iid}) #{@mr_status}")) - end - end - - # Over rides default behaviour to show source/target - # Formats arguments into a String suitable for use as an email subject - # - # extra - Extra Strings to be inserted into the subject - # - # Examples - # - # >> subject('Lorem ipsum') - # => "GitLab Merge Request | Lorem ipsum" - # - # # Automatically inserts Project name: - # Forked MR - # => source project => - # => target project => - # => source branch => source - # => target branch => target - # >> subject('Lorem ipsum') - # => "GitLab Merge Request | Ruby on Rails:source >> My Ror:target | Lorem ipsum " - # - # Non Forked MR - # => source project => - # => target project => - # => source branch => source - # => target branch => target - # >> subject('Lorem ipsum') - # => "GitLab Merge Request | Ruby on Rails | source >> target | Lorem ipsum " - # # Accepts multiple arguments - # >> subject('Lorem ipsum', 'Dolor sit amet') - # => "GitLab Merge Request | Lorem ipsum | Dolor sit amet" - def subject(*extra) - subject = "Merge Request | " - if @merge_request.for_fork? - subject << "#{@merge_request.source_project.name_with_namespace}:#{merge_request.source_branch} >> #{@merge_request.target_project.name_with_namespace}:#{merge_request.target_branch}" - else - subject << "#{@merge_request.source_project.name_with_namespace} | #{merge_request.source_branch} >> #{merge_request.target_branch}" - end - subject << " | " + extra.join(' | ') if extra.present? - subject - end - -end diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb deleted file mode 100644 index ff251209e01e2d6c4f82c61167080f183e378c7c..0000000000000000000000000000000000000000 --- a/app/mailers/emails/notes.rb +++ /dev/null @@ -1,43 +0,0 @@ -module Emails - module Notes - def note_commit_email(recipient_id, note_id) - @note = Note.find(note_id) - @commit = @note.noteable - @project = @note.project - @target_url = namespace_project_commit_url(@project.namespace, @project, - @commit, anchor: - "note_#{@note.id}") - mail_answer_thread(@commit, - from: sender(@note.author_id), - to: recipient(recipient_id), - subject: subject("#{@commit.title} (#{@commit.short_id})")) - end - - def note_issue_email(recipient_id, note_id) - @note = Note.find(note_id) - @issue = @note.noteable - @project = @note.project - @target_url = namespace_project_issue_url(@project.namespace, @project, - @issue, anchor: - "note_#{@note.id}") - mail_answer_thread(@issue, - from: sender(@note.author_id), - to: recipient(recipient_id), - subject: subject("#{@issue.title} (##{@issue.iid})")) - end - - def note_merge_request_email(recipient_id, note_id) - @note = Note.find(note_id) - @merge_request = @note.noteable - @project = @note.project - @target_url = namespace_project_merge_request_url(@project.namespace, - @project, - @merge_request, anchor: - "note_#{@note.id}") - mail_answer_thread(@merge_request, - from: sender(@note.author_id), - to: recipient(recipient_id), - subject: subject("#{@merge_request.title} (##{@merge_request.iid})")) - end - end -end diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb deleted file mode 100644 index 3a83b0831099783ca7853d1abb7943c9b0169958..0000000000000000000000000000000000000000 --- a/app/mailers/emails/profile.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Emails - module Profile - def new_user_email(user_id, token = nil) - @current_user = @user = User.find(user_id) - @target_url = user_url(@user) - @token = token - mail(to: @user.notification_email, subject: subject("Account was created for you")) - end - - def new_email_email(email_id) - @email = Email.find(email_id) - @current_user = @user = @email.user - mail(to: @user.notification_email, subject: subject("Email was added to your account")) - end - - def new_ssh_key_email(key_id) - @key = Key.find(key_id) - @current_user = @user = @key.user - @target_url = user_url(@user) - mail(to: @user.notification_email, subject: subject("SSH key was added to your account")) - end - end -end diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb deleted file mode 100644 index 0dbb2939bb30c33702d54cd8c4225c955908bc84..0000000000000000000000000000000000000000 --- a/app/mailers/emails/projects.rb +++ /dev/null @@ -1,141 +0,0 @@ -module Emails - module Projects - def project_access_granted_email(project_member_id) - @project_member = ProjectMember.find project_member_id - @project = @project_member.project - - @target_url = namespace_project_url(@project.namespace, @project) - @current_user = @project_member.user - - mail(to: @project_member.user.notification_email, - subject: subject("Access to project was granted")) - end - - def project_member_invited_email(project_member_id, token) - @project_member = ProjectMember.find project_member_id - @project = @project_member.project - @token = token - - @target_url = namespace_project_url(@project.namespace, @project) - @current_user = @project_member.user - - mail(to: @project_member.invite_email, - subject: "Invitation to join project #{@project.name_with_namespace}") - end - - def project_invite_accepted_email(project_member_id) - @project_member = ProjectMember.find project_member_id - return if @project_member.created_by.nil? - - @project = @project_member.project - - @target_url = namespace_project_url(@project.namespace, @project) - @current_user = @project_member.created_by - - mail(to: @project_member.created_by.notification_email, - subject: subject("Invitation accepted")) - end - - def project_invite_declined_email(project_id, invite_email, access_level, created_by_id) - return if created_by_id.nil? - - @project = Project.find(project_id) - @current_user = @created_by = User.find(created_by_id) - @access_level = access_level - @invite_email = invite_email - - @target_url = namespace_project_url(@project.namespace, @project) - - mail(to: @created_by.notification_email, - subject: subject("Invitation declined")) - end - - def project_was_moved_email(project_id, user_id) - @current_user = @user = User.find user_id - @project = Project.find project_id - @target_url = namespace_project_url(@project.namespace, @project) - mail(to: @user.notification_email, - subject: subject("Project was moved")) - end - - def repository_push_email(project_id, recipient, author_id: nil, - ref: nil, - action: nil, - compare: nil, - reverse_compare: false, - send_from_committer_email: false, - disable_diffs: false) - unless author_id && ref && action - raise ArgumentError, "missing keywords: author_id, ref, action" - end - - @project = Project.find(project_id) - @current_user = @author = User.find(author_id) - @reverse_compare = reverse_compare - @compare = compare - @ref_name = Gitlab::Git.ref_name(ref) - @ref_type = Gitlab::Git.tag_ref?(ref) ? "tag" : "branch" - @action = action - @disable_diffs = disable_diffs - - if @compare - @commits = Commit.decorate(compare.commits) - @diffs = compare.diffs - end - - @action_name = - case action - when :create - "pushed new" - when :delete - "deleted" - else - "pushed to" - end - - @subject = "[#{@project.path_with_namespace}]" - @subject << "[#{@ref_name}]" if action == :push - @subject << " " - - if action == :push - if @commits.length > 1 - @target_url = namespace_project_compare_url(@project.namespace, - @project, - from: Commit.new(@compare.base), - to: Commit.new(@compare.head)) - @subject << "Deleted " if @reverse_compare - @subject << "#{@commits.length} commits: #{@commits.first.title}" - else - @target_url = namespace_project_commit_url(@project.namespace, - @project, @commits.first) - - @subject << "Deleted 1 commit: " if @reverse_compare - @subject << @commits.first.title - end - else - unless action == :delete - @target_url = namespace_project_tree_url(@project.namespace, - @project, @ref_name) - end - - subject_action = @action_name.dup - subject_action[0] = subject_action[0].capitalize - @subject << "#{subject_action} #{@ref_type} #{@ref_name}" - end - - @disable_footer = true - - reply_to = - if send_from_committer_email && can_send_from_user_email?(@author) - @author.email - else - Gitlab.config.gitlab.email_reply_to - end - - mail(from: sender(author_id, send_from_committer_email), - reply_to: reply_to, - to: recipient, - subject: @subject) - end - end -end diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb deleted file mode 100644 index 2c0d451511f284aa1c3bd07c7831bb5a81ff7e2a..0000000000000000000000000000000000000000 --- a/app/mailers/notify.rb +++ /dev/null @@ -1,167 +0,0 @@ -class Notify < ActionMailer::Base - include ActionDispatch::Routing::PolymorphicRoutes - - include Emails::Issues - include Emails::MergeRequests - include Emails::Notes - include Emails::Projects - include Emails::Profile - include Emails::Groups - - add_template_helper ApplicationHelper - add_template_helper GitlabMarkdownHelper - add_template_helper MergeRequestsHelper - add_template_helper EmailsHelper - - attr_accessor :current_user - helper_method :current_user, :can? - - default_url_options[:host] = Gitlab.config.gitlab.host - default_url_options[:protocol] = Gitlab.config.gitlab.protocol - default_url_options[:port] = Gitlab.config.gitlab.port unless Gitlab.config.gitlab_on_standard_port? - default_url_options[:script_name] = Gitlab.config.gitlab.relative_url_root - - default from: Proc.new { default_sender_address.format } - default reply_to: Gitlab.config.gitlab.email_reply_to - - # Just send email with 2 seconds delay - def self.delay - delay_for(2.seconds) - end - - def test_email(recipient_email, subject, body) - mail(to: recipient_email, - subject: subject, - body: body.html_safe, - content_type: 'text/html' - ) - end - - # Splits "gitlab.corp.company.com" up into "gitlab.corp.company.com", - # "corp.company.com" and "company.com". - # Respects set tld length so "company.co.uk" won't match "somethingelse.uk" - def self.allowed_email_domains - domain_parts = Gitlab.config.gitlab.host.split(".") - allowed_domains = [] - begin - allowed_domains << domain_parts.join(".") - domain_parts.shift - end while domain_parts.length > ActionDispatch::Http::URL.tld_length - - allowed_domains - end - - private - - # The default email address to send emails from - def default_sender_address - address = Mail::Address.new(Gitlab.config.gitlab.email_from) - address.display_name = Gitlab.config.gitlab.email_display_name - address - end - - def can_send_from_user_email?(sender) - sender_domain = sender.email.split("@").last - self.class.allowed_email_domains.include?(sender_domain) - end - - # Return an email address that displays the name of the sender. - # Only the displayed name changes; the actual email address is always the same. - def sender(sender_id, send_from_user_email = false) - return unless sender = User.find(sender_id) - - address = default_sender_address - address.display_name = sender.name - - if send_from_user_email && can_send_from_user_email?(sender) - address.address = sender.email - end - - address.format - end - - # Look up a User by their ID and return their email address - # - # recipient_id - User ID - # - # Returns a String containing the User's email address. - def recipient(recipient_id) - @current_user = User.find(recipient_id) - @current_user.notification_email - end - - # Set the References header field - # - # local_part - The local part of the referenced message ID - # - def set_reference(local_part) - headers["References"] = "<#{local_part}@#{Gitlab.config.gitlab.host}>" - end - - # Formats arguments into a String suitable for use as an email subject - # - # extra - Extra Strings to be inserted into the subject - # - # Examples - # - # >> subject('Lorem ipsum') - # => "Lorem ipsum" - # - # # Automatically inserts Project name when @project is set - # >> @project = Project.last - # => # - # >> subject('Lorem ipsum') - # => "Ruby on Rails | Lorem ipsum " - # - # # Accepts multiple arguments - # >> subject('Lorem ipsum', 'Dolor sit amet') - # => "Lorem ipsum | Dolor sit amet" - def subject(*extra) - subject = "" - subject << "#{@project.name} | " if @project - subject << extra.join(' | ') if extra.present? - subject - end - - # Return a string suitable for inclusion in the 'Message-Id' mail header. - # - # The message-id is generated from the unique URL to a model object. - def message_id(model) - model_name = model.class.model_name.singular_route_key - "<#{model_name}_#{model.id}@#{Gitlab.config.gitlab.host}>" - end - - # Send an email that starts a new conversation thread, - # with headers suitable for grouping by thread in email clients. - # - # See: mail_answer_thread - def mail_new_thread(model, headers = {}, &block) - headers['Message-ID'] = message_id(model) - headers['X-GitLab-Project'] = "#{@project.name} | " if @project - mail(headers, &block) - end - - # Send an email that responds to an existing conversation thread, - # with headers suitable for grouping by thread in email clients. - # - # For grouping emails by thread, email clients heuristics require the answers to: - # - # * have a subject that begin by 'Re: ' - # * have a 'In-Reply-To' or 'References' header that references the original 'Message-ID' - # - def mail_answer_thread(model, headers = {}, &block) - headers['In-Reply-To'] = message_id(model) - headers['References'] = message_id(model) - headers['X-GitLab-Project'] = "#{@project.name} | " if @project - - if headers[:subject] - headers[:subject].prepend('Re: ') - end - - mail(headers, &block) - end - - def can? - Ability.abilities.allowed?(user, action, subject) - end -end diff --git a/app/models/.gitkeep b/app/models/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/app/models/ability.rb b/app/models/ability.rb deleted file mode 100644 index 85a15596f8d75066a6186bd962b149eb7afd8e21..0000000000000000000000000000000000000000 --- a/app/models/ability.rb +++ /dev/null @@ -1,276 +0,0 @@ -class Ability - class << self - def allowed(user, subject) - return not_auth_abilities(user, subject) if user.nil? - return [] unless user.kind_of?(User) - return [] if user.blocked? - - case subject.class.name - when "Project" then project_abilities(user, subject) - when "Issue" then issue_abilities(user, subject) - when "Note" then note_abilities(user, subject) - when "ProjectSnippet" then project_snippet_abilities(user, subject) - when "PersonalSnippet" then personal_snippet_abilities(user, subject) - when "MergeRequest" then merge_request_abilities(user, subject) - when "Group" then group_abilities(user, subject) - when "Namespace" then namespace_abilities(user, subject) - when "GroupMember" then group_member_abilities(user, subject) - else [] - end.concat(global_abilities(user)) - end - - # List of possible abilities - # for non-authenticated user - def not_auth_abilities(user, subject) - project = if subject.kind_of?(Project) - subject - elsif subject.respond_to?(:project) - subject.project - else - nil - end - - if project && project.public? - [ - :read_project, - :read_wiki, - :read_issue, - :read_milestone, - :read_project_snippet, - :read_project_member, - :read_merge_request, - :read_note, - :download_code - ] - else - group = if subject.kind_of?(Group) - subject - elsif subject.respond_to?(:group) - subject.group - else - nil - end - - if group && group.public_profile? - [:read_group] - else - [] - end - end - end - - def global_abilities(user) - rules = [] - rules << :create_group if user.can_create_group - rules - end - - def project_abilities(user, project) - rules = [] - key = "/user/#{user.id}/project/#{project.id}" - RequestStore.store[key] ||= begin - team = project.team - - # Rules based on role in project - if team.master?(user) - rules.push(*project_master_rules) - - elsif team.developer?(user) - rules.push(*project_dev_rules) - - elsif team.reporter?(user) - rules.push(*project_report_rules) - - elsif team.guest?(user) - rules.push(*project_guest_rules) - end - - if project.public? || project.internal? - rules.push(*public_project_rules) - end - - if project.owner == user || user.admin? - rules.push(*project_admin_rules) - end - - if project.group && project.group.has_owner?(user) - rules.push(*project_admin_rules) - end - - if project.archived? - rules -= project_archived_rules - end - - rules - end - end - - def public_project_rules - project_guest_rules + [ - :download_code, - :fork_project - ] - end - - def project_guest_rules - [ - :read_project, - :read_wiki, - :read_issue, - :read_milestone, - :read_project_snippet, - :read_project_member, - :read_merge_request, - :read_note, - :write_project, - :write_issue, - :write_note - ] - end - - def project_report_rules - project_guest_rules + [ - :download_code, - :fork_project, - :write_project_snippet - ] - end - - def project_dev_rules - project_report_rules + [ - :write_merge_request, - :write_wiki, - :modify_issue, - :admin_issue, - :admin_label, - :push_code - ] - end - - def project_archived_rules - [ - :write_merge_request, - :push_code, - :push_code_to_protected_branches, - :modify_merge_request, - :admin_merge_request - ] - end - - def project_master_rules - project_dev_rules + [ - :push_code_to_protected_branches, - :modify_issue, - :modify_project_snippet, - :modify_merge_request, - :admin_issue, - :admin_milestone, - :admin_project_snippet, - :admin_project_member, - :admin_merge_request, - :admin_note, - :admin_wiki, - :admin_project - ] - end - - def project_admin_rules - project_master_rules + [ - :change_namespace, - :change_visibility_level, - :rename_project, - :remove_project, - :archive_project - ] - end - - def group_abilities(user, group) - rules = [] - - if user.admin? || group.users.include?(user) || ProjectsFinder.new.execute(user, group: group).any? - rules << :read_group - end - - # Only group masters and group owners can create new projects in group - if group.has_master?(user) || group.has_owner?(user) || user.admin? - rules.push(*[ - :create_projects, - ]) - end - - # Only group owner and administrators can admin group - if group.has_owner?(user) || user.admin? - rules.push(*[ - :admin_group, - :admin_namespace - ]) - end - - rules.flatten - end - - def namespace_abilities(user, namespace) - rules = [] - - # Only namespace owner and administrators can admin it - if namespace.owner == user || user.admin? - rules.push(*[ - :create_projects, - :admin_namespace - ]) - end - - rules.flatten - end - - [:issue, :note, :project_snippet, :personal_snippet, :merge_request].each do |name| - define_method "#{name}_abilities" do |user, subject| - if subject.author == user || user.is_admin? - rules = [ - :"read_#{name}", - :"write_#{name}", - :"modify_#{name}", - :"admin_#{name}" - ] - rules.push(:change_visibility_level) if subject.is_a?(Snippet) - rules - elsif subject.respond_to?(:assignee) && subject.assignee == user - [ - :"read_#{name}", - :"write_#{name}", - :"modify_#{name}", - ] - else - if subject.respond_to?(:project) - project_abilities(user, subject.project) - else - [] - end - end - end - end - - def group_member_abilities(user, subject) - rules = [] - target_user = subject.user - group = subject.group - can_manage = group_abilities(user, group).include?(:admin_group) - if can_manage && (user != target_user) - rules << :modify_group_member - rules << :destroy_group_member - end - if !group.last_owner?(user) && (can_manage || (user == target_user)) - rules << :destroy_group_member - end - rules - end - - def abilities - @abilities ||= begin - abilities = Six.new - abilities << self - abilities - end - end - end -end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb deleted file mode 100644 index 0d8365c4ff2c78442b84b71ee3453049e583d733..0000000000000000000000000000000000000000 --- a/app/models/application_setting.rb +++ /dev/null @@ -1,61 +0,0 @@ -# == Schema Information -# -# Table name: application_settings -# -# id :integer not null, primary key -# default_projects_limit :integer -# default_branch_protection :integer -# signup_enabled :boolean -# signin_enabled :boolean -# gravatar_enabled :boolean -# twitter_sharing_enabled :boolean -# sign_in_text :text -# created_at :datetime -# updated_at :datetime -# home_page_url :string(255) -# default_branch_protection :integer default(2) -# twitter_sharing_enabled :boolean default(TRUE) -# restricted_visibility_levels :text -# max_attachment_size :integer default(10) -# - -class ApplicationSetting < ActiveRecord::Base - serialize :restricted_visibility_levels - - validates :home_page_url, - allow_blank: true, - format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, - if: :home_page_url_column_exist - - validates_each :restricted_visibility_levels do |record, attr, value| - unless value.nil? - value.each do |level| - unless Gitlab::VisibilityLevel.options.has_value?(level) - record.errors.add(attr, "'#{level}' is not a valid visibility level") - end - end - end - end - - def self.current - ApplicationSetting.last - end - - def self.create_from_defaults - create( - default_projects_limit: Settings.gitlab['default_projects_limit'], - default_branch_protection: Settings.gitlab['default_branch_protection'], - signup_enabled: Settings.gitlab['signup_enabled'], - signin_enabled: Settings.gitlab['signin_enabled'], - twitter_sharing_enabled: Settings.gitlab['twitter_sharing_enabled'], - gravatar_enabled: Settings.gravatar['enabled'], - sign_in_text: Settings.extra['sign_in_text'], - restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'], - max_attachment_size: Settings.gitlab['max_attachment_size'] - ) - end - - def home_page_url_column_exist - ActiveRecord::Base.connection.column_exists?(:application_settings, :home_page_url) - end -end diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb deleted file mode 100644 index 05f5e9796959d577298a87dd0bc366f24d686865..0000000000000000000000000000000000000000 --- a/app/models/broadcast_message.rb +++ /dev/null @@ -1,29 +0,0 @@ -# == Schema Information -# -# Table name: broadcast_messages -# -# id :integer not null, primary key -# message :text not null -# starts_at :datetime -# ends_at :datetime -# alert_type :integer -# created_at :datetime -# updated_at :datetime -# color :string(255) -# font :string(255) -# - -class BroadcastMessage < ActiveRecord::Base - include Sortable - - validates :message, presence: true - validates :starts_at, presence: true - validates :ends_at, presence: true - - validates :color, format: { with: /\A\#[0-9A-Fa-f]{3}{1,2}+\Z/ }, allow_blank: true - validates :font, format: { with: /\A\#[0-9A-Fa-f]{3}{1,2}+\Z/ }, allow_blank: true - - def self.current - where("ends_at > :now AND starts_at < :now", now: Time.zone.now).last - end -end diff --git a/app/models/commit.rb b/app/models/commit.rb deleted file mode 100644 index 006fa62c8f96bd86e16c02390e7282cdef352240..0000000000000000000000000000000000000000 --- a/app/models/commit.rb +++ /dev/null @@ -1,155 +0,0 @@ -class Commit - include ActiveModel::Conversion - include StaticModel - extend ActiveModel::Naming - include Mentionable - - attr_mentionable :safe_message - - # Safe amount of changes (files and lines) in one commit to render - # Used to prevent 500 error on huge commits by suppressing diff - # - # User can force display of diff above this size - DIFF_SAFE_FILES = 100 unless defined?(DIFF_SAFE_FILES) - DIFF_SAFE_LINES = 5000 unless defined?(DIFF_SAFE_LINES) - - # Commits above this size will not be rendered in HTML - DIFF_HARD_LIMIT_FILES = 1000 unless defined?(DIFF_HARD_LIMIT_FILES) - DIFF_HARD_LIMIT_LINES = 50000 unless defined?(DIFF_HARD_LIMIT_LINES) - - class << self - def decorate(commits) - commits.map do |commit| - if commit.kind_of?(Commit) - commit - else - self.new(commit) - end - end - end - - # Calculate number of lines to render for diffs - def diff_line_count(diffs) - diffs.reduce(0) { |sum, d| sum + d.diff.lines.count } - end - - # Truncate sha to 8 characters - def truncate_sha(sha) - sha[0..7] - end - end - - attr_accessor :raw - - def initialize(raw_commit) - raise "Nil as raw commit passed" unless raw_commit - - @raw = raw_commit - end - - def id - @raw.id - end - - def diff_line_count - @diff_line_count ||= Commit::diff_line_count(self.diffs) - @diff_line_count - end - - # Returns a string describing the commit for use in a link title - # - # Example - # - # "Commit: Alex Denisov - Project git clone panel" - def link_title - "Commit: #{author_name} - #{title}" - end - - # Returns the commits title. - # - # Usually, the commit title is the first line of the commit message. - # In case this first line is longer than 100 characters, it is cut off - # after 80 characters and ellipses (`&hellp;`) are appended. - def title - title = safe_message - - return no_commit_message if title.blank? - - title_end = title.index("\n") - if (!title_end && title.length > 100) || (title_end && title_end > 100) - title[0..79] << "…" - else - title.split("\n", 2).first - end - end - - # Returns the commits description - # - # cut off, ellipses (`&hellp;`) are prepended to the commit message. - def description - title_end = safe_message.index("\n") - @description ||= - if (!title_end && safe_message.length > 100) || (title_end && title_end > 100) - "…" << safe_message[80..-1] - else - safe_message.split("\n", 2)[1].try(:chomp) - end - end - - def description? - description.present? - end - - def hook_attrs(project) - path_with_namespace = project.path_with_namespace - - { - id: id, - message: safe_message, - timestamp: committed_date.xmlschema, - url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{id}", - author: { - name: author_name, - email: author_email - } - } - end - - # Discover issues should be closed when this commit is pushed to a project's - # default branch. - def closes_issues(project, current_user = self.committer) - Gitlab::ClosingIssueExtractor.new(project, current_user).closed_by_message(safe_message) - end - - # Mentionable override. - def gfm_reference - "commit #{id}" - end - - def author - User.find_for_commit(author_email, author_name) - end - - def committer - User.find_for_commit(committer_email, committer_name) - end - - def method_missing(m, *args, &block) - @raw.send(m, *args, &block) - end - - def respond_to?(method) - return true if @raw.respond_to?(method) - - super - end - - # Truncate sha to 8 characters - def short_id - @raw.short_id(7) - end - - def parents - @parents ||= Commit.decorate(super) - end -end diff --git a/app/models/concerns/internal_id.rb b/app/models/concerns/internal_id.rb deleted file mode 100644 index 821ed54fb987568a3fd41c638709127e1fefccb1..0000000000000000000000000000000000000000 --- a/app/models/concerns/internal_id.rb +++ /dev/null @@ -1,17 +0,0 @@ -module InternalId - extend ActiveSupport::Concern - - included do - validate :set_iid, on: :create - validates :iid, presence: true, numericality: true - end - - def set_iid - max_iid = project.send(self.class.name.tableize).maximum(:iid) - self.iid = max_iid.to_i + 1 - end - - def to_param - iid.to_s - end -end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb deleted file mode 100644 index 478134dff68f8fa11f42c8b52ffd7750fdc60314..0000000000000000000000000000000000000000 --- a/app/models/concerns/issuable.rb +++ /dev/null @@ -1,189 +0,0 @@ -# == Issuable concern -# -# Contains common functionality shared between Issues and MergeRequests -# -# Used by Issue, MergeRequest -# -module Issuable - extend ActiveSupport::Concern - include Mentionable - - included do - belongs_to :author, class_name: "User" - belongs_to :assignee, class_name: "User" - belongs_to :milestone - has_many :notes, as: :noteable, dependent: :destroy - has_many :label_links, as: :target, dependent: :destroy - has_many :labels, through: :label_links - has_many :subscriptions, dependent: :destroy, as: :subscribable - - validates :author, presence: true - validates :title, presence: true, length: { within: 0..255 } - - scope :authored, ->(user) { where(author_id: user) } - scope :assigned_to, ->(u) { where(assignee_id: u.id)} - scope :recent, -> { order("created_at DESC") } - scope :assigned, -> { where("assignee_id IS NOT NULL") } - scope :unassigned, -> { where("assignee_id IS NULL") } - scope :of_projects, ->(ids) { where(project_id: ids) } - scope :opened, -> { with_state(:opened, :reopened) } - scope :only_opened, -> { with_state(:opened) } - scope :only_reopened, -> { with_state(:reopened) } - scope :closed, -> { with_state(:closed) } - scope :order_milestone_due_desc, -> { joins(:milestone).reorder('milestones.due_date DESC, milestones.id DESC') } - scope :order_milestone_due_asc, -> { joins(:milestone).reorder('milestones.due_date ASC, milestones.id ASC') } - - delegate :name, - :email, - to: :author, - prefix: true - - delegate :name, - :email, - to: :assignee, - allow_nil: true, - prefix: true - - attr_mentionable :title, :description - end - - module ClassMethods - def search(query) - where("LOWER(title) like :query", query: "%#{query.downcase}%") - end - - def full_search(query) - where("LOWER(title) like :query OR LOWER(description) like :query", query: "%#{query.downcase}%") - end - - def sort(method) - case method.to_s - when 'milestone_due_asc' then order_milestone_due_asc - when 'milestone_due_desc' then order_milestone_due_desc - else - order_by(method) - end - end - end - - def today? - Date.today == created_at.to_date - end - - def new? - today? && created_at == updated_at - end - - def is_assigned? - !!assignee_id - end - - def is_being_reassigned? - assignee_id_changed? - end - - # - # Votes - # - - # Return the number of -1 comments (downvotes) - def downvotes - filter_superceded_votes(notes.select(&:downvote?), notes).size - end - - def downvotes_in_percent - if votes_count.zero? - 0 - else - 100.0 - upvotes_in_percent - end - end - - # Return the number of +1 comments (upvotes) - def upvotes - filter_superceded_votes(notes.select(&:upvote?), notes).size - end - - def upvotes_in_percent - if votes_count.zero? - 0 - else - 100.0 / votes_count * upvotes - end - end - - # Return the total number of votes - def votes_count - upvotes + downvotes - end - - # Return all users participating on the discussion - def participants(current_user = self.author) - users = [] - users << author - users << assignee if is_assigned? - mentions = [] - mentions << self.mentioned_users(current_user) - - notes.each do |note| - users << note.author - mentions << note.mentioned_users(current_user) - end - - users.concat(mentions.reduce([], :|)).uniq - end - - def subscribed?(user) - subscription = subscriptions.find_by_user_id(user.id) - - if subscription - return subscription.subscribed - end - - participants(user).include?(user) - end - - def toggle_subscription(user) - subscriptions. - find_or_initialize_by(user_id: user.id). - update(subscribed: !subscribed?(user)) - end - - def to_hook_data(user) - { - object_kind: self.class.name.underscore, - user: user.hook_attrs, - object_attributes: hook_attrs - } - end - - def label_names - labels.order('title ASC').pluck(:title) - end - - def remove_labels - labels.delete_all - end - - def add_labels_by_names(label_names) - label_names.each do |label_name| - label = project.labels.create_with(color: Label::DEFAULT_COLOR). - find_or_create_by(title: label_name.strip) - self.labels << label - end - end - - private - - def filter_superceded_votes(votes, notes) - filteredvotes = [] + votes - - votes.each do |vote| - if vote.superceded?(notes) - filteredvotes.delete(vote) - end - end - - filteredvotes - end -end diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb deleted file mode 100644 index b7882a2bb160253b1ef2492e445a71c874232385..0000000000000000000000000000000000000000 --- a/app/models/concerns/mentionable.rb +++ /dev/null @@ -1,89 +0,0 @@ -# == Mentionable concern -# -# Contains functionality related to objects that can mention Users, Issues, MergeRequests, or Commits by -# GFM references. -# -# Used by Issue, Note, MergeRequest, and Commit. -# -module Mentionable - extend ActiveSupport::Concern - - module ClassMethods - # Indicate which attributes of the Mentionable to search for GFM references. - def attr_mentionable(*attrs) - mentionable_attrs.concat(attrs.map(&:to_s)) - end - - # Accessor for attributes marked mentionable. - def mentionable_attrs - @mentionable_attrs ||= [] - end - end - - # Generate a GFM back-reference that will construct a link back to this Mentionable when rendered. Must - # be overridden if this model object can be referenced directly by GFM notation. - def gfm_reference - raise NotImplementedError.new("#{self.class} does not implement #gfm_reference") - end - - # Construct a String that contains possible GFM references. - def mentionable_text - self.class.mentionable_attrs.map { |attr| send(attr) || '' }.join - end - - # The GFM reference to this Mentionable, which shouldn't be included in its #references. - def local_reference - self - end - - # Determine whether or not a cross-reference Note has already been created between this Mentionable and - # the specified target. - def has_mentioned?(target) - Note.cross_reference_exists?(target, local_reference) - end - - def mentioned_users(current_user = nil) - return [] if mentionable_text.blank? - - ext = Gitlab::ReferenceExtractor.new(self.project, current_user) - ext.analyze(mentionable_text) - ext.users.uniq - end - - # Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference. - def references(p = project, current_user = self.author, text = mentionable_text) - return [] if text.blank? - - ext = Gitlab::ReferenceExtractor.new(p, current_user) - ext.analyze(text) - - (ext.issues + ext.merge_requests + ext.commits).uniq - [local_reference] - end - - # Create a cross-reference Note for each GFM reference to another Mentionable found in +mentionable_text+. - def create_cross_references!(p = project, a = author, without = []) - refs = references(p) - without - refs.each do |ref| - Note.create_cross_reference_note(ref, local_reference, a, p) - end - end - - # If the mentionable_text field is about to change, locate any *added* references and create cross references for - # them. Invoke from an observer's #before_save implementation. - def notice_added_references(p = project, a = author) - ch = changed_attributes - original, mentionable_changed = "", false - self.class.mentionable_attrs.each do |attr| - if ch[attr] - original << ch[attr] - mentionable_changed = true - end - end - - # Only proceed if the saved changes actually include a chance to an attr_mentionable field. - return unless mentionable_changed - - preexisting = references(p, self.author, original) - create_cross_references!(p, a, preexisting) - end -end diff --git a/app/models/concerns/notifiable.rb b/app/models/concerns/notifiable.rb deleted file mode 100644 index d7dcd97911dd4825987855a38d5723e6550180d4..0000000000000000000000000000000000000000 --- a/app/models/concerns/notifiable.rb +++ /dev/null @@ -1,15 +0,0 @@ -# == Notifiable concern -# -# Contains notification functionality -# -module Notifiable - extend ActiveSupport::Concern - - included do - validates :notification_level, inclusion: { in: Notification.project_notification_levels }, presence: true - end - - def notification - @notification ||= Notification.new(self) - end -end diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb deleted file mode 100644 index 0ad2654867d767ca1e18955ab773d81ce59a23f3..0000000000000000000000000000000000000000 --- a/app/models/concerns/sortable.rb +++ /dev/null @@ -1,35 +0,0 @@ -# == Sortable concern -# -# Set default scope for ordering objects -# -module Sortable - extend ActiveSupport::Concern - - included do - # By default all models should be ordered - # by created_at field starting from newest - default_scope { order(created_at: :desc, id: :desc) } - - scope :order_created_desc, -> { reorder(created_at: :desc, id: :desc) } - scope :order_created_asc, -> { reorder(created_at: :asc, id: :asc) } - scope :order_updated_desc, -> { reorder(updated_at: :desc, id: :desc) } - scope :order_updated_asc, -> { reorder(updated_at: :asc, id: :asc) } - scope :order_name_asc, -> { reorder(name: :asc) } - scope :order_name_desc, -> { reorder(name: :desc) } - end - - module ClassMethods - def order_by(method) - case method.to_s - when 'name_asc' then order_name_asc - when 'name_desc' then order_name_desc - when 'updated_asc' then order_updated_asc - when 'updated_desc' then order_updated_desc - when 'created_asc' then order_created_asc - when 'created_desc' then order_created_desc - else - all - end - end - end -end diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb deleted file mode 100644 index bbb3b301a9f5a1392ed6a97cdb9946de79c3258e..0000000000000000000000000000000000000000 --- a/app/models/concerns/taskable.rb +++ /dev/null @@ -1,51 +0,0 @@ -# Contains functionality for objects that can have task lists in their -# descriptions. Task list items can be added with Markdown like "* [x] Fix -# bugs". -# -# Used by MergeRequest and Issue -module Taskable - TASK_PATTERN_MD = /^(? *[*-] *)\[(?[ xX])\]/.freeze - TASK_PATTERN_HTML = /^
  • (?\s*

    )?\[(?[ xX])\]/.freeze - - # Change the state of a task list item for this Taskable. Edit the object's - # description by finding the nth task item and changing its checkbox - # placeholder to "[x]" if +checked+ is true, or "[ ]" if it's false. - # Note: task numbering starts with 1 - def update_nth_task(n, checked) - index = 0 - check_char = checked ? 'x' : ' ' - - # Do this instead of using #gsub! so that ActiveRecord detects that a field - # has changed. - self.description = self.description.gsub(TASK_PATTERN_MD) do |match| - index += 1 - case index - when n then "#{$LAST_MATCH_INFO[:bullet]}[#{check_char}]" - else match - end - end - - save - end - - # Return true if this object's description has any task list items. - def tasks? - description && description.match(TASK_PATTERN_MD) - end - - # Return a string that describes the current state of this Taskable's task - # list items, e.g. "20 tasks (12 done, 8 unfinished)" - def task_status - return nil unless description - - num_tasks = 0 - num_done = 0 - - description.scan(TASK_PATTERN_MD) do - num_tasks += 1 - num_done += 1 unless $LAST_MATCH_INFO[:checked] == ' ' - end - - "#{num_tasks} tasks (#{num_done} done, #{num_tasks - num_done} unfinished)" - end -end diff --git a/app/models/concerns/token_authenticatable.rb b/app/models/concerns/token_authenticatable.rb deleted file mode 100644 index 9b88ec1cc3840f3e70afacdca7666ce19551783c..0000000000000000000000000000000000000000 --- a/app/models/concerns/token_authenticatable.rb +++ /dev/null @@ -1,31 +0,0 @@ -module TokenAuthenticatable - extend ActiveSupport::Concern - - module ClassMethods - def find_by_authentication_token(authentication_token = nil) - if authentication_token - where(authentication_token: authentication_token).first - end - end - end - - def ensure_authentication_token - if authentication_token.blank? - self.authentication_token = generate_authentication_token - end - end - - def reset_authentication_token! - self.authentication_token = generate_authentication_token - save - end - - private - - def generate_authentication_token - loop do - token = Devise.friendly_token - break token unless self.class.unscoped.where(authentication_token: token).first - end - end -end diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb deleted file mode 100644 index 85d52d558cd0a8730ca53e5a84c50f75cb68eb62..0000000000000000000000000000000000000000 --- a/app/models/deploy_key.rb +++ /dev/null @@ -1,38 +0,0 @@ -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime -# updated_at :datetime -# key :text -# public :boolean default(FALSE) -# title :string(255) -# type :string(255) -# fingerprint :string(255) -# - -class DeployKey < Key - has_many :deploy_keys_projects, dependent: :destroy - has_many :projects, through: :deploy_keys_projects - - scope :in_projects, ->(projects) { joins(:deploy_keys_projects).where('deploy_keys_projects.project_id in (?)', projects) } - scope :are_public, -> { where(public: true) } - - def private? - !public? - end - - def orphaned? - self.deploy_keys_projects.length == 0 - end - - def almost_orphaned? - self.deploy_keys_projects.length == 1 - end - - def destroyed_when_orphaned? - self.private? - end -end diff --git a/app/models/deploy_keys_project.rb b/app/models/deploy_keys_project.rb deleted file mode 100644 index 18db521741fba8e6b9bb752ad54c551ada19a25f..0000000000000000000000000000000000000000 --- a/app/models/deploy_keys_project.rb +++ /dev/null @@ -1,29 +0,0 @@ -# == Schema Information -# -# Table name: deploy_keys_projects -# -# id :integer not null, primary key -# deploy_key_id :integer not null -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - -class DeployKeysProject < ActiveRecord::Base - belongs_to :project - belongs_to :deploy_key - - validates :deploy_key_id, presence: true - validates :deploy_key_id, uniqueness: { scope: [:project_id], message: "already exists in project" } - validates :project_id, presence: true - - after_destroy :destroy_orphaned_deploy_key - - private - - def destroy_orphaned_deploy_key - return unless self.deploy_key.destroyed_when_orphaned? && self.deploy_key.orphaned? - - self.deploy_key.destroy - end -end diff --git a/app/models/diff_line.rb b/app/models/diff_line.rb deleted file mode 100644 index ad37945874a69fd21511b0646f1344273e9a6b17..0000000000000000000000000000000000000000 --- a/app/models/diff_line.rb +++ /dev/null @@ -1,3 +0,0 @@ -class DiffLine - attr_accessor :type, :content, :num, :code -end diff --git a/app/models/email.rb b/app/models/email.rb deleted file mode 100644 index 556b0e9586e72d8f23c99feaae8e53e17cfbc710..0000000000000000000000000000000000000000 --- a/app/models/email.rb +++ /dev/null @@ -1,35 +0,0 @@ -# == Schema Information -# -# Table name: emails -# -# id :integer not null, primary key -# user_id :integer not null -# email :string(255) not null -# created_at :datetime -# updated_at :datetime -# - -class Email < ActiveRecord::Base - include Sortable - - belongs_to :user - - validates :user_id, presence: true - validates :email, presence: true, email: { strict_mode: true }, uniqueness: true - validate :unique_email, if: ->(email) { email.email_changed? } - - after_create :notify - before_validation :cleanup_email - - def cleanup_email - self.email = self.email.downcase.strip - end - - def unique_email - self.errors.add(:email, 'has already been taken') if User.exists?(email: self.email) - end - - def notify - NotificationService.new.new_email(self) - end -end diff --git a/app/models/event.rb b/app/models/event.rb deleted file mode 100644 index c9a88ffa8e0fe93362d75f534f9614e545853f31..0000000000000000000000000000000000000000 --- a/app/models/event.rb +++ /dev/null @@ -1,330 +0,0 @@ -# == Schema Information -# -# Table name: events -# -# id :integer not null, primary key -# target_type :string(255) -# target_id :integer -# title :string(255) -# data :text -# project_id :integer -# created_at :datetime -# updated_at :datetime -# action :integer -# author_id :integer -# - -class Event < ActiveRecord::Base - include Sortable - default_scope { where.not(author_id: nil) } - - CREATED = 1 - UPDATED = 2 - CLOSED = 3 - REOPENED = 4 - PUSHED = 5 - COMMENTED = 6 - MERGED = 7 - JOINED = 8 # User joined project - LEFT = 9 # User left project - - delegate :name, :email, to: :author, prefix: true, allow_nil: true - delegate :title, to: :issue, prefix: true, allow_nil: true - delegate :title, to: :merge_request, prefix: true, allow_nil: true - delegate :title, to: :note, prefix: true, allow_nil: true - - belongs_to :author, class_name: "User" - belongs_to :project - belongs_to :target, polymorphic: true - - # For Hash only - serialize :data - - # Callbacks - after_create :reset_project_activity - - # Scopes - scope :recent, -> { order("created_at DESC") } - scope :code_push, -> { where(action: PUSHED) } - scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent } - scope :with_associations, -> { includes(project: :namespace) } - - class << self - def reset_event_cache_for(target) - Event.where(target_id: target.id, target_type: target.class.to_s). - order('id DESC').limit(100). - update_all(updated_at: Time.now) - end - - def contributions - where("action = ? OR (target_type in (?) AND action in (?))", - Event::PUSHED, ["MergeRequest", "Issue"], - [Event::CREATED, Event::CLOSED, Event::MERGED]) - end - end - - def proper? - if push? - true - elsif membership_changed? - true - elsif created_project? - true - else - (issue? || merge_request? || note? || milestone?) && target - end - end - - def project_name - if project - project.name_with_namespace - else - "(deleted project)" - end - end - - def target_title - target.title if target && target.respond_to?(:title) - end - - def created? - action == CREATED - end - - def push? - action == PUSHED && valid_push? - end - - def merged? - action == MERGED - end - - def closed? - action == CLOSED - end - - def reopened? - action == REOPENED - end - - def joined? - action == JOINED - end - - def left? - action == LEFT - end - - def commented? - action == COMMENTED - end - - def membership_changed? - joined? || left? - end - - def created_project? - created? && !target - end - - def created_target? - created? && target - end - - def milestone? - target_type == "Milestone" - end - - def note? - target_type == "Note" - end - - def issue? - target_type == "Issue" - end - - def merge_request? - target_type == "MergeRequest" - end - - def milestone - target if milestone? - end - - def issue - target if issue? - end - - def merge_request - target if merge_request? - end - - def note - target if note? - end - - def action_name - if push? - if new_ref? - "pushed new" - elsif rm_ref? - "deleted" - else - "pushed to" - end - elsif closed? - "closed" - elsif merged? - "accepted" - elsif joined? - 'joined' - elsif left? - 'left' - elsif commented? - "commented on" - elsif created_project? - if project.import? - "imported" - else - "created" - end - else - "opened" - end - end - - def valid_push? - data[:ref] && ref_name.present? - rescue - false - end - - def tag? - Gitlab::Git.tag_ref?(data[:ref]) - end - - def branch? - Gitlab::Git.branch_ref?(data[:ref]) - end - - def new_ref? - Gitlab::Git.blank_ref?(commit_from) - end - - def rm_ref? - Gitlab::Git.blank_ref?(commit_to) - end - - def md_ref? - !(rm_ref? || new_ref?) - end - - def commit_from - data[:before] - end - - def commit_to - data[:after] - end - - def ref_name - if tag? - tag_name - else - branch_name - end - end - - def branch_name - @branch_name ||= Gitlab::Git.ref_name(data[:ref]) - end - - def tag_name - @tag_name ||= Gitlab::Git.ref_name(data[:ref]) - end - - # Max 20 commits from push DESC - def commits - @commits ||= (data[:commits] || []).reverse - end - - def commits_count - data[:total_commits_count] || commits.count || 0 - end - - def ref_type - tag? ? "tag" : "branch" - end - - def push_with_commits? - !commits.empty? && commit_from && commit_to - end - - def last_push_to_non_root? - branch? && project.default_branch != branch_name - end - - def note_commit_id - target.commit_id - end - - def target_iid - target.respond_to?(:iid) ? target.iid : target_id - end - - def note_short_commit_id - Commit.truncate_sha(note_commit_id) - end - - def note_commit? - target.noteable_type == "Commit" - end - - def note_project_snippet? - target.noteable_type == "Snippet" - end - - def note_target - target.noteable - end - - def note_target_id - if note_commit? - target.commit_id - else - target.noteable_id.to_s - end - end - - def note_target_iid - if note_target.respond_to?(:iid) - note_target.iid - else - note_target_id - end.to_s - end - - def note_target_type - if target.noteable_type.present? - target.noteable_type.titleize - else - "Wall" - end.downcase - end - - def body? - if push? - push_with_commits? - elsif note? - true - else - target.respond_to? :title - end - end - - def reset_project_activity - if project - project.update_column(:last_activity_at, self.created_at) - end - end -end diff --git a/app/models/external_issue.rb b/app/models/external_issue.rb deleted file mode 100644 index 50efcb32f1b9f93c41dd20e858a9405e97e4543a..0000000000000000000000000000000000000000 --- a/app/models/external_issue.rb +++ /dev/null @@ -1,25 +0,0 @@ -class ExternalIssue - def initialize(issue_identifier, project) - @issue_identifier, @project = issue_identifier, project - end - - def to_s - @issue_identifier.to_s - end - - def id - @issue_identifier.to_s - end - - def iid - @issue_identifier.to_s - end - - def ==(other) - other.is_a?(self.class) && (to_s == other.to_s) - end - - def project - @project - end -end diff --git a/app/models/forked_project_link.rb b/app/models/forked_project_link.rb deleted file mode 100644 index 9b0c6263a96ac65713a977e90c4cc568225b1d1e..0000000000000000000000000000000000000000 --- a/app/models/forked_project_link.rb +++ /dev/null @@ -1,15 +0,0 @@ -# == Schema Information -# -# Table name: forked_project_links -# -# id :integer not null, primary key -# forked_to_project_id :integer not null -# forked_from_project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - -class ForkedProjectLink < ActiveRecord::Base - belongs_to :forked_to_project, class_name: Project - belongs_to :forked_from_project, class_name: Project -end diff --git a/app/models/group.rb b/app/models/group.rb deleted file mode 100644 index 1386a9eccc9dece0ba96dd65c164c42a523443af..0000000000000000000000000000000000000000 --- a/app/models/group.rb +++ /dev/null @@ -1,100 +0,0 @@ -# == Schema Information -# -# Table name: namespaces -# -# id :integer not null, primary key -# name :string(255) not null -# path :string(255) not null -# owner_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) -# description :string(255) default(""), not null -# avatar :string(255) -# - -require 'carrierwave/orm/activerecord' -require 'file_size_validator' - -class Group < Namespace - has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember' - has_many :users, through: :group_members - - validate :avatar_type, if: ->(user) { user.avatar_changed? } - validates :avatar, file_size: { maximum: 200.kilobytes.to_i } - - mount_uploader :avatar, AvatarUploader - - after_create :post_create_hook - after_destroy :post_destroy_hook - - class << self - def search(query) - where("LOWER(namespaces.name) LIKE :query or LOWER(namespaces.path) LIKE :query", query: "%#{query.downcase}%") - end - - def sort(method) - order_by(method) - end - end - - def human_name - name - end - - def owners - @owners ||= group_members.owners.map(&:user) - end - - def add_users(user_ids, access_level, current_user = nil) - user_ids.each do |user_id| - Member.add_user(self.group_members, user_id, access_level, current_user) - end - end - - def add_user(user, access_level, current_user = nil) - add_users([user], access_level, current_user) - end - - def add_owner(user, current_user = nil) - self.add_user(user, Gitlab::Access::OWNER, current_user) - end - - def has_owner?(user) - owners.include?(user) - end - - def has_master?(user) - members.masters.where(user_id: user).any? - end - - def last_owner?(user) - has_owner?(user) && owners.size == 1 - end - - def members - group_members - end - - def avatar_type - unless self.avatar.image? - self.errors.add :avatar, "only images allowed" - end - end - - def public_profile? - projects.public_only.any? - end - - def post_create_hook - system_hook_service.execute_hooks_for(self, :create) - end - - def post_destroy_hook - system_hook_service.execute_hooks_for(self, :destroy) - end - - def system_hook_service - SystemHooksService.new - end -end diff --git a/app/models/group_milestone.rb b/app/models/group_milestone.rb deleted file mode 100644 index 7e4f16ebf167ee51bf45bd4cecc10d470fb980cc..0000000000000000000000000000000000000000 --- a/app/models/group_milestone.rb +++ /dev/null @@ -1,95 +0,0 @@ -class GroupMilestone - - def initialize(title, milestones) - @title = title - @milestones = milestones - end - - def title - @title - end - - def safe_title - @title.parameterize - end - - def milestones - @milestones - end - - def projects - milestones.map { |milestone| milestone.project } - end - - def issue_count - milestones.map { |milestone| milestone.issues.count }.sum - end - - def merge_requests_count - milestones.map { |milestone| milestone.merge_requests.count }.sum - end - - def open_items_count - milestones.map { |milestone| milestone.open_items_count }.sum - end - - def closed_items_count - milestones.map { |milestone| milestone.closed_items_count }.sum - end - - def total_items_count - milestones.map { |milestone| milestone.total_items_count }.sum - end - - def percent_complete - ((closed_items_count * 100) / total_items_count).abs - rescue ZeroDivisionError - 100 - end - - def state - state = milestones.map { |milestone| milestone.state } - - if state.count('closed') == state.size - 'closed' - else - 'active' - end - end - - def active? - state == 'active' - end - - def closed? - state == 'closed' - end - - def issues - @group_issues ||= milestones.map(&:issues).flatten.group_by(&:state) - end - - def merge_requests - @group_merge_requests ||= milestones.map(&:merge_requests).flatten.group_by(&:state) - end - - def participants - @group_participants ||= milestones.map(&:participants).flatten.compact.uniq - end - - def opened_issues - issues.values_at("opened", "reopened").compact.flatten - end - - def closed_issues - issues['closed'] - end - - def opened_merge_requests - merge_requests.values_at("opened", "reopened").compact.flatten - end - - def closed_merge_requests - merge_requests.values_at("closed", "merged", "locked").compact.flatten - end -end diff --git a/app/models/hooks/project_hook.rb b/app/models/hooks/project_hook.rb deleted file mode 100644 index 21867a9316c37c79d87d32093fbb9a1226a82b45..0000000000000000000000000000000000000000 --- a/app/models/hooks/project_hook.rb +++ /dev/null @@ -1,25 +0,0 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# - -class ProjectHook < WebHook - belongs_to :project - - scope :push_hooks, -> { where(push_events: true) } - scope :tag_push_hooks, -> { where(tag_push_events: true) } - scope :issue_hooks, -> { where(issues_events: true) } - scope :merge_request_hooks, -> { where(merge_requests_events: true) } -end diff --git a/app/models/hooks/service_hook.rb b/app/models/hooks/service_hook.rb deleted file mode 100644 index 2e11239c40b5c688197908d8b9c6333cc442090a..0000000000000000000000000000000000000000 --- a/app/models/hooks/service_hook.rb +++ /dev/null @@ -1,20 +0,0 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# - -class ServiceHook < WebHook - belongs_to :service -end diff --git a/app/models/hooks/system_hook.rb b/app/models/hooks/system_hook.rb deleted file mode 100644 index ee32b49bc66ef182d056229d4bf497b3699e0744..0000000000000000000000000000000000000000 --- a/app/models/hooks/system_hook.rb +++ /dev/null @@ -1,19 +0,0 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# - -class SystemHook < WebHook -end diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb deleted file mode 100644 index 315d96af1b9fa04bd8de97d44cff861fc81429d8..0000000000000000000000000000000000000000 --- a/app/models/hooks/web_hook.rb +++ /dev/null @@ -1,60 +0,0 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# - -class WebHook < ActiveRecord::Base - include Sortable - include HTTParty - - default_value_for :push_events, true - default_value_for :issues_events, false - default_value_for :merge_requests_events, false - default_value_for :tag_push_events, false - - # HTTParty timeout - default_timeout Gitlab.config.gitlab.webhook_timeout - - validates :url, presence: true, - format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" } - - def execute(data) - parsed_url = URI.parse(url) - if parsed_url.userinfo.blank? - WebHook.post(url, - body: data.to_json, - headers: { "Content-Type" => "application/json" }, - verify: false) - else - post_url = url.gsub("#{parsed_url.userinfo}@", "") - auth = { - username: URI.decode(parsed_url.user), - password: URI.decode(parsed_url.password), - } - WebHook.post(post_url, - body: data.to_json, - headers: { "Content-Type" => "application/json" }, - verify: false, - basic_auth: auth) - end - rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e - logger.error("WebHook Error => #{e}") - false - end - - def async_execute(data) - Sidekiq::Client.enqueue(ProjectWebHookWorker, id, data) - end -end diff --git a/app/models/identity.rb b/app/models/identity.rb deleted file mode 100644 index 756d19adec70ffff347f52df7d0a522e8cae4f69..0000000000000000000000000000000000000000 --- a/app/models/identity.rb +++ /dev/null @@ -1,19 +0,0 @@ -# == Schema Information -# -# Table name: identities -# -# id :integer not null, primary key -# extern_uid :string(255) -# provider :string(255) -# user_id :integer -# created_at :datetime -# updated_at :datetime -# - -class Identity < ActiveRecord::Base - include Sortable - belongs_to :user - - validates :extern_uid, allow_blank: true, uniqueness: { scope: :provider } - validates :user_id, uniqueness: { scope: :provider } -end diff --git a/app/models/issue.rb b/app/models/issue.rb deleted file mode 100644 index 6e1020513875aba4f1af2d3e21f8a9d37d25850e..0000000000000000000000000000000000000000 --- a/app/models/issue.rb +++ /dev/null @@ -1,78 +0,0 @@ -# == Schema Information -# -# Table name: issues -# -# id :integer not null, primary key -# title :string(255) -# assignee_id :integer -# author_id :integer -# project_id :integer -# created_at :datetime -# updated_at :datetime -# position :integer default(0) -# branch_name :string(255) -# description :text -# milestone_id :integer -# state :string(255) -# iid :integer -# - -require 'carrierwave/orm/activerecord' -require 'file_size_validator' - -class Issue < ActiveRecord::Base - include Issuable - include InternalId - include Taskable - include Sortable - - ActsAsTaggableOn.strict_case_match = true - - belongs_to :project - validates :project, presence: true - - scope :of_group, ->(group) { where(project_id: group.project_ids) } - scope :cared, ->(user) { where(assignee_id: user) } - scope :open_for, ->(user) { opened.assigned_to(user) } - - state_machine :state, initial: :opened do - event :close do - transition [:reopened, :opened] => :closed - end - - event :reopen do - transition closed: :reopened - end - - state :opened - state :reopened - state :closed - end - - def hook_attrs - attributes - end - - # Mentionable overrides. - - def gfm_reference - "issue ##{iid}" - end - - # Reset issue events cache - # - # Since we do cache @event we need to reset cache in special cases: - # * when an issue is updated - # Events cache stored like events/23-20130109142513. - # The cache key includes updated_at timestamp. - # Thus it will automatically generate a new fragment - # when the event is updated because the key changes. - def reset_events_cache - Event.reset_event_cache_for(self) - end - - # To allow polymorphism with MergeRequest. - def source_project - project - end -end diff --git a/app/models/key.rb b/app/models/key.rb deleted file mode 100644 index 016eee86992e51e11cd98f8238f3a701059e52b7..0000000000000000000000000000000000000000 --- a/app/models/key.rb +++ /dev/null @@ -1,86 +0,0 @@ -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime -# updated_at :datetime -# key :text -# title :string(255) -# type :string(255) -# fingerprint :string(255) -# - -require 'digest/md5' - -class Key < ActiveRecord::Base - include Sortable - - belongs_to :user - - before_validation :strip_white_space, :generate_fingerprint - - validates :title, presence: true, length: { within: 0..255 } - validates :key, presence: true, length: { within: 0..5000 }, format: { with: /\A(ssh|ecdsa)-.*\Z/ }, uniqueness: true - validates :fingerprint, uniqueness: true, presence: { message: 'cannot be generated' } - - delegate :name, :email, to: :user, prefix: true - - after_create :add_to_shell - after_create :notify_user - after_create :post_create_hook - after_destroy :remove_from_shell - after_destroy :post_destroy_hook - - def strip_white_space - self.key = key.strip unless key.blank? - end - - # projects that has this key - def projects - user.authorized_projects - end - - def shell_id - "key-#{id}" - end - - def add_to_shell - GitlabShellWorker.perform_async( - :add_key, - shell_id, - key - ) - end - - def notify_user - NotificationService.new.new_key(self) - end - - def post_create_hook - SystemHooksService.new.execute_hooks_for(self, :create) - end - - def remove_from_shell - GitlabShellWorker.perform_async( - :remove_key, - shell_id, - key, - ) - end - - def post_destroy_hook - SystemHooksService.new.execute_hooks_for(self, :destroy) - end - - private - - def generate_fingerprint - self.fingerprint = nil - - return unless self.key.present? - - self.fingerprint = Gitlab::KeyFingerprint.new(self.key).fingerprint - end -end diff --git a/app/models/label_link.rb b/app/models/label_link.rb deleted file mode 100644 index b94c9c777af3109afe8cb86712063451c2c51dc0..0000000000000000000000000000000000000000 --- a/app/models/label_link.rb +++ /dev/null @@ -1,19 +0,0 @@ -# == Schema Information -# -# Table name: label_links -# -# id :integer not null, primary key -# label_id :integer -# target_id :integer -# target_type :string(255) -# created_at :datetime -# updated_at :datetime -# - -class LabelLink < ActiveRecord::Base - belongs_to :target, polymorphic: true - belongs_to :label - - validates :target, presence: true - validates :label, presence: true -end diff --git a/app/models/member.rb b/app/models/member.rb deleted file mode 100644 index d151c7b2390b9b637b5e79ea7d26cdfced395ace..0000000000000000000000000000000000000000 --- a/app/models/member.rb +++ /dev/null @@ -1,172 +0,0 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string(255) not null -# user_id :integer not null -# notification_level :integer not null -# type :string(255) -# created_at :datetime -# updated_at :datetime -# created_by_id :integer -# invite_email :string -# invite_token :string -# invite_accepted_at :datetime -# - -class Member < ActiveRecord::Base - include Sortable - include Notifiable - include Gitlab::Access - - attr_accessor :raw_invite_token - - belongs_to :created_by, class_name: "User" - belongs_to :user - belongs_to :source, polymorphic: true - - validates :user, presence: true, unless: :invite? - validates :source, presence: true - validates :user_id, uniqueness: { scope: [:source_type, :source_id], - message: "already exists in source", - allow_nil: true } - validates :access_level, inclusion: { in: Gitlab::Access.all_values }, presence: true - validates :invite_email, presence: { if: :invite? }, - email: { strict_mode: true, allow_nil: true }, - uniqueness: { scope: [:source_type, :source_id], allow_nil: true } - - scope :invite, -> { where(user_id: nil) } - scope :non_invite, -> { where("user_id IS NOT NULL") } - scope :guests, -> { where(access_level: GUEST) } - scope :reporters, -> { where(access_level: REPORTER) } - scope :developers, -> { where(access_level: DEVELOPER) } - scope :masters, -> { where(access_level: MASTER) } - scope :owners, -> { where(access_level: OWNER) } - - before_validation :generate_invite_token, on: :create, if: -> (member) { member.invite_email.present? } - after_create :send_invite, if: :invite? - after_create :post_create_hook, unless: :invite? - after_update :post_update_hook, unless: :invite? - after_destroy :post_destroy_hook, unless: :invite? - - delegate :name, :username, :email, to: :user, prefix: true - - class << self - def find_by_invite_token(invite_token) - invite_token = Devise.token_generator.digest(self, :invite_token, invite_token) - find_by(invite_token: invite_token) - end - - # This method is used to find users that have been entered into the "Add members" field. - # These can be the User objects directly, their IDs, their emails, or new emails to be invited. - def user_for_id(user_id) - return user_id if user_id.is_a?(User) - - user = User.find_by(id: user_id) - user ||= User.find_by(email: user_id) - user ||= user_id - user - end - - def add_user(members, user_id, access_level, current_user = nil) - user = user_for_id(user_id) - - # `user` can be either a User object or an email to be invited - if user.is_a?(User) - member = members.find_or_initialize_by(user_id: user.id) - else - member = members.build - member.invite_email = user - end - - member.created_by ||= current_user - member.access_level = access_level - - member.save - end - end - - def invite? - self.invite_token.present? - end - - def accept_invite!(new_user) - return false unless invite? - - self.invite_token = nil - self.invite_accepted_at = Time.now.utc - - self.user = new_user - - saved = self.save - - after_accept_invite if saved - - saved - end - - def decline_invite! - return false unless invite? - - destroyed = self.destroy - - after_decline_invite if destroyed - - destroyed - end - - def generate_invite_token - raw, enc = Devise.token_generator.generate(self.class, :invite_token) - @raw_invite_token = raw - self.invite_token = enc - end - - def generate_invite_token! - generate_invite_token && save(validate: false) - end - - def resend_invite - return unless invite? - - generate_invite_token! unless @raw_invite_token - - send_invite - end - - private - - def send_invite - # override in subclass - end - - def post_create_hook - system_hook_service.execute_hooks_for(self, :create) - end - - def post_update_hook - # override in subclass - end - - def post_destroy_hook - system_hook_service.execute_hooks_for(self, :destroy) - end - - def after_accept_invite - post_create_hook - end - - def after_decline_invite - # override in subclass - end - - def system_hook_service - SystemHooksService.new - end - - def notification_service - NotificationService.new - end -end diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb deleted file mode 100644 index 84c91372b3f6469c5d1228fb9efb3584f314b8af..0000000000000000000000000000000000000000 --- a/app/models/members/group_member.rb +++ /dev/null @@ -1,75 +0,0 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string(255) not null -# user_id :integer not null -# notification_level :integer not null -# type :string(255) -# created_at :datetime -# updated_at :datetime -# - -class GroupMember < Member - SOURCE_TYPE = 'Namespace' - - belongs_to :group, class_name: 'Group', foreign_key: 'source_id' - - # Make sure group member points only to group as it source - default_value_for :source_type, SOURCE_TYPE - default_value_for :notification_level, Notification::N_GLOBAL - validates_format_of :source_type, with: /\ANamespace\z/ - default_scope { where(source_type: SOURCE_TYPE) } - - scope :with_group, ->(group) { where(source_id: group.id) } - scope :with_user, ->(user) { where(user_id: user.id) } - - def self.access_level_roles - Gitlab::Access.options_with_owner - end - - def group - source - end - - def access_field - access_level - end - - private - - def send_invite - notification_service.invite_group_member(self, @raw_invite_token) - - super - end - - def post_create_hook - notification_service.new_group_member(self) - - super - end - - def post_update_hook - if access_level_changed? - notification_service.update_group_member(self) - end - - super - end - - def after_accept_invite - notification_service.accept_group_invite(self) - - super - end - - def after_decline_invite - notification_service.decline_group_invite(self) - - super - end -end diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb deleted file mode 100644 index 0a3b4d2182b2d8a2196cd45eb46627b2bc5c80ed..0000000000000000000000000000000000000000 --- a/app/models/members/project_member.rb +++ /dev/null @@ -1,165 +0,0 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string(255) not null -# user_id :integer not null -# notification_level :integer not null -# type :string(255) -# created_at :datetime -# updated_at :datetime -# - -class ProjectMember < Member - SOURCE_TYPE = 'Project' - - include Gitlab::ShellAdapter - - belongs_to :project, class_name: 'Project', foreign_key: 'source_id' - - - # Make sure project member points only to project as it source - default_value_for :source_type, SOURCE_TYPE - default_value_for :notification_level, Notification::N_GLOBAL - validates_format_of :source_type, with: /\AProject\z/ - default_scope { where(source_type: SOURCE_TYPE) } - - scope :in_project, ->(project) { where(source_id: project.id) } - scope :in_projects, ->(projects) { where(source_id: projects.pluck(:id)) } - scope :with_user, ->(user) { where(user_id: user.id) } - - class << self - - # Add users to project teams with passed access option - # - # access can be an integer representing a access code - # or symbol like :master representing role - # - # Ex. - # add_users_into_projects( - # project_ids, - # user_ids, - # ProjectMember::MASTER - # ) - # - # add_users_into_projects( - # project_ids, - # user_ids, - # :master - # ) - # - def add_users_into_projects(project_ids, user_ids, access, current_user = nil) - access_level = if roles_hash.has_key?(access) - roles_hash[access] - elsif roles_hash.values.include?(access.to_i) - access - else - raise "Non valid access" - end - - users = user_ids.map { |user_id| Member.user_for_id(user_id) } - - ProjectMember.transaction do - project_ids.each do |project_id| - project = Project.find(project_id) - - users.each do |user| - Member.add_user(project.project_members, user, access_level, current_user) - end - end - end - - true - rescue - false - end - - def truncate_teams(project_ids) - ProjectMember.transaction do - members = ProjectMember.where(source_id: project_ids) - - members.each do |member| - member.destroy - end - end - - true - rescue - false - end - - def truncate_team(project) - truncate_teams [project.id] - end - - def roles_hash - Gitlab::Access.sym_options - end - - def access_roles - Gitlab::Access.options - end - end - - def access_field - access_level - end - - def project - source - end - - def owner? - project.owner == user - end - - private - - def send_invite - notification_service.invite_project_member(self, @raw_invite_token) - - super - end - - def post_create_hook - unless owner? - event_service.join_project(self.project, self.user) - notification_service.new_project_member(self) - end - - super - end - - def post_update_hook - if access_level_changed? - notification_service.update_project_member(self) - end - - super - end - - def post_destroy_hook - event_service.leave_project(self.project, self.user) - - super - end - - def after_accept_invite - notification_service.accept_project_invite(self) - - super - end - - def after_decline_invite - notification_service.decline_project_invite(self) - - super - end - - def event_service - EventCreateService.new - end -end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb deleted file mode 100644 index 9c9e27625070d0f9dc4637540ada6b8ad2fda5bb..0000000000000000000000000000000000000000 --- a/app/models/merge_request.rb +++ /dev/null @@ -1,368 +0,0 @@ -# == Schema Information -# -# Table name: merge_requests -# -# id :integer not null, primary key -# target_branch :string(255) not null -# source_branch :string(255) not null -# source_project_id :integer not null -# author_id :integer -# assignee_id :integer -# title :string(255) -# created_at :datetime -# updated_at :datetime -# milestone_id :integer -# state :string(255) -# merge_status :string(255) -# target_project_id :integer not null -# iid :integer -# description :text -# position :integer default(0) -# locked_at :datetime -# - -require Rails.root.join("app/models/commit") -require Rails.root.join("lib/static_model") - -class MergeRequest < ActiveRecord::Base - include Issuable - include Taskable - include InternalId - include Sortable - - belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project" - belongs_to :source_project, foreign_key: :source_project_id, class_name: "Project" - - has_one :merge_request_diff, dependent: :destroy - - after_create :create_merge_request_diff - after_update :update_merge_request_diff - - delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil - - attr_accessor :should_remove_source_branch - - # When this attribute is true some MR validation is ignored - # It allows us to close or modify broken merge requests - attr_accessor :allow_broken - - # Temporary fields to store compare vars - # when creating new merge request - attr_accessor :can_be_created, :compare_failed, - :compare_commits, :compare_diffs - - state_machine :state, initial: :opened do - event :close do - transition [:reopened, :opened] => :closed - end - - event :merge do - transition [:reopened, :opened, :locked] => :merged - end - - event :reopen do - transition closed: :reopened - end - - event :lock_mr do - transition [:reopened, :opened] => :locked - end - - event :unlock_mr do - transition locked: :reopened - end - - after_transition any => :locked do |merge_request, transition| - merge_request.locked_at = Time.now - merge_request.save - end - - after_transition locked: (any - :locked) do |merge_request, transition| - merge_request.locked_at = nil - merge_request.save - end - - state :opened - state :reopened - state :closed - state :merged - state :locked - end - - state_machine :merge_status, initial: :unchecked do - event :mark_as_unchecked do - transition [:can_be_merged, :cannot_be_merged] => :unchecked - end - - event :mark_as_mergeable do - transition [:unchecked, :cannot_be_merged] => :can_be_merged - end - - event :mark_as_unmergeable do - transition [:unchecked, :can_be_merged] => :cannot_be_merged - end - - state :unchecked - state :can_be_merged - state :cannot_be_merged - - around_transition do |merge_request, transition, block| - merge_request.record_timestamps = false - begin - block.call - ensure - merge_request.record_timestamps = true - end - end - end - - validates :source_project, presence: true, unless: :allow_broken - validates :source_branch, presence: true - validates :target_project, presence: true - validates :target_branch, presence: true - validate :validate_branches - validate :validate_fork - - scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.project_ids) } - scope :merged, -> { with_state(:merged) } - scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) } - scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) } - scope :by_milestone, ->(milestone) { where(milestone_id: milestone) } - scope :in_projects, ->(project_ids) { where("source_project_id in (:project_ids) OR target_project_id in (:project_ids)", project_ids: project_ids) } - scope :of_projects, ->(ids) { where(target_project_id: ids) } - # Closed scope for merge request should return - # both merged and closed mr's - scope :closed, -> { with_states(:closed, :merged) } - scope :declined, -> { with_states(:closed) } - - def validate_branches - if target_project == source_project && target_branch == source_branch - errors.add :branch_conflict, "You can not use same project/branch for source and target" - end - - if opened? || reopened? - similar_mrs = self.target_project.merge_requests.where(source_branch: source_branch, target_branch: target_branch, source_project_id: source_project.id).opened - similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id - if similar_mrs.any? - errors.add :validate_branches, - "Cannot Create: This merge request already exists: #{ - similar_mrs.pluck(:title) - }" - end - end - end - - def validate_fork - return true unless target_project && source_project - - if target_project == source_project - true - else - # If source and target projects are different - # we should check if source project is actually a fork of target project - if source_project.forked_from?(target_project) - true - else - errors.add :validate_fork, - 'Source project is not a fork of target project' - end - end - end - - def update_merge_request_diff - if source_branch_changed? || target_branch_changed? - reload_code - mark_as_unchecked - end - end - - def reload_code - if merge_request_diff && open? - merge_request_diff.reload_content - end - end - - def check_if_can_be_merged - if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged? - mark_as_mergeable - else - mark_as_unmergeable - end - end - - def merge_event - self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last - end - - def closed_event - self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last - end - - def automerge!(current_user, commit_message = nil) - MergeRequests::AutoMergeService. - new(target_project, current_user). - execute(self, commit_message) - end - - def open? - opened? || reopened? - end - - def mr_and_commit_notes - # Fetch comments only from last 100 commits - commits_for_notes_limit = 100 - commit_ids = commits.last(commits_for_notes_limit).map(&:id) - - project.notes.where( - "(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))", - mr_id: id, - commit_ids: commit_ids - ) - end - - # Returns the raw diff for this merge request - # - # see "git diff" - def to_diff(current_user) - Gitlab::Satellite::MergeAction.new(current_user, self).diff_in_satellite - end - - # Returns the commit as a series of email patches. - # - # see "git format-patch" - def to_patch(current_user) - Gitlab::Satellite::MergeAction.new(current_user, self).format_patch - end - - def hook_attrs - attrs = { - source: source_project.hook_attrs, - target: target_project.hook_attrs, - last_commit: nil - } - - unless last_commit.nil? - attrs.merge!(last_commit: last_commit.hook_attrs(source_project)) - end - - attributes.merge!(attrs) - end - - def for_fork? - target_project != source_project - end - - def project - target_project - end - - # Return the set of issues that will be closed if this merge request is accepted. - def closes_issues(current_user = self.author) - if target_branch == project.default_branch - issues = commits.flat_map { |c| c.closes_issues(project, current_user) } - issues.push(*Gitlab::ClosingIssueExtractor.new(project, current_user). - closed_by_message(description)) - issues.uniq.sort_by(&:id) - else - [] - end - end - - # Mentionable override. - def gfm_reference - "merge request !#{iid}" - end - - def target_project_path - if target_project - target_project.path_with_namespace - else - "(removed)" - end - end - - def source_project_path - if source_project - source_project.path_with_namespace - else - "(removed)" - end - end - - def source_project_namespace - if source_project && source_project.namespace - source_project.namespace.path - else - "(removed)" - end - end - - def target_project_namespace - if target_project && target_project.namespace - target_project.namespace.path - else - "(removed)" - end - end - - def source_branch_exists? - return false unless self.source_project - - self.source_project.repository.branch_names.include?(self.source_branch) - end - - def target_branch_exists? - return false unless self.target_project - - self.target_project.repository.branch_names.include?(self.target_branch) - end - - # Reset merge request events cache - # - # Since we do cache @event we need to reset cache in special cases: - # * when a merge request is updated - # Events cache stored like events/23-20130109142513. - # The cache key includes updated_at timestamp. - # Thus it will automatically generate a new fragment - # when the event is updated because the key changes. - def reset_events_cache - Event.reset_event_cache_for(self) - end - - def merge_commit_message - message = "Merge branch '#{source_branch}' into '#{target_branch}'" - message << "\n\n" - message << title.to_s - message << "\n\n" - message << description.to_s - message << "\n\n" - message << "See merge request !#{iid}" - message - end - - # Return array of possible target branches - # depends on target project of MR - def target_branches - if target_project.nil? - [] - else - target_project.repository.branch_names - end - end - - # Return array of possible source branches - # depends on source project of MR - def source_branches - if source_project.nil? - [] - else - source_project.repository.branch_names - end - end - - def locked_long_ago? - return false unless locked? - - locked_at.nil? || locked_at < (Time.now - 1.day) - end -end diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb deleted file mode 100644 index acac1ca4cf7ca2e3ccabbf70e754f6402d730e19..0000000000000000000000000000000000000000 --- a/app/models/merge_request_diff.rb +++ /dev/null @@ -1,171 +0,0 @@ -# == Schema Information -# -# Table name: merge_request_diffs -# -# id :integer not null, primary key -# state :string(255) -# st_commits :text -# st_diffs :text -# merge_request_id :integer not null -# created_at :datetime -# updated_at :datetime -# - -require Rails.root.join("app/models/commit") - -class MergeRequestDiff < ActiveRecord::Base - include Sortable - - # Prevent store of diff - # if commits amount more then 200 - COMMITS_SAFE_SIZE = 200 - - attr_reader :commits, :diffs - - belongs_to :merge_request - - delegate :target_branch, :source_branch, to: :merge_request, prefix: nil - - state_machine :state, initial: :empty do - state :collected - state :timeout - state :overflow_commits_safe_size - state :overflow_diff_files_limit - state :overflow_diff_lines_limit - end - - serialize :st_commits - serialize :st_diffs - - after_create :reload_content - - def reload_content - reload_commits - reload_diffs - end - - def diffs - @diffs ||= (load_diffs(st_diffs) || []) - end - - def commits - @commits ||= load_commits(st_commits || []) - end - - def last_commit - commits.first - end - - def last_commit_short_sha - @last_commit_short_sha ||= last_commit.short_id - end - - private - - def dump_commits(commits) - commits.map(&:to_hash) - end - - def load_commits(array) - array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash)) } - end - - def dump_diffs(diffs) - if diffs.respond_to?(:map) - diffs.map(&:to_hash) - end - end - - def load_diffs(raw) - if raw.respond_to?(:map) - raw.map { |hash| Gitlab::Git::Diff.new(hash) } - end - end - - # Collect array of Git::Commit objects - # between target and source branches - def unmerged_commits - commits = compare_result.commits - - if commits.present? - commits = Commit.decorate(commits). - sort_by(&:created_at). - reverse - end - - commits - end - - # Reload all commits related to current merge request from repo - # and save it as array of hashes in st_commits db field - def reload_commits - commit_objects = unmerged_commits - - if commit_objects.present? - self.st_commits = dump_commits(commit_objects) - end - - save - end - - # Reload diffs between branches related to current merge request from repo - # and save it as array of hashes in st_diffs db field - def reload_diffs - new_diffs = [] - - if commits.size.zero? - self.state = :empty - elsif commits.size > COMMITS_SAFE_SIZE - self.state = :overflow_commits_safe_size - else - new_diffs = unmerged_diffs - end - - if new_diffs.any? - if new_diffs.size > Commit::DIFF_HARD_LIMIT_FILES - self.state = :overflow_diff_files_limit - new_diffs = [] - end - - if new_diffs.sum { |diff| diff.diff.lines.count } > Commit::DIFF_HARD_LIMIT_LINES - self.state = :overflow_diff_lines_limit - new_diffs = [] - end - end - - if new_diffs.present? - new_diffs = dump_commits(new_diffs) - self.state = :collected - end - - self.st_diffs = new_diffs - self.save - end - - # Collect array of Git::Diff objects - # between target and source branches - def unmerged_diffs - diffs = compare_result.diffs - diffs ||= [] - diffs - rescue Gitlab::Git::Diff::TimeoutError => ex - self.state = :timeout - diffs = [] - end - - def repository - merge_request.target_project.repository - end - - private - - def compare_result - @compare_result ||= CompareService.new.execute( - merge_request.author, - merge_request.source_project, - merge_request.source_branch, - merge_request.target_project, - merge_request.target_branch, - ) - end -end diff --git a/app/models/milestone.rb b/app/models/milestone.rb deleted file mode 100644 index 9bbb2bafb981c1398adf5cedf65e091145b0e40f..0000000000000000000000000000000000000000 --- a/app/models/milestone.rb +++ /dev/null @@ -1,93 +0,0 @@ -# == Schema Information -# -# Table name: milestones -# -# id :integer not null, primary key -# title :string(255) not null -# project_id :integer not null -# description :text -# due_date :date -# created_at :datetime -# updated_at :datetime -# state :string(255) -# iid :integer -# - -class Milestone < ActiveRecord::Base - include InternalId - include Sortable - - belongs_to :project - has_many :issues - has_many :merge_requests - has_many :participants, through: :issues, source: :assignee - - scope :active, -> { with_state(:active) } - scope :closed, -> { with_state(:closed) } - scope :of_projects, ->(ids) { where(project_id: ids) } - - validates :title, presence: true - validates :project, presence: true - - state_machine :state, initial: :active do - event :close do - transition active: :closed - end - - event :activate do - transition closed: :active - end - - state :closed - - state :active - end - - def expired? - if due_date - due_date.past? - else - false - end - end - - def open_items_count - self.issues.opened.count + self.merge_requests.opened.count - end - - def closed_items_count - self.issues.closed.count + self.merge_requests.closed.count - end - - def total_items_count - self.issues.count + self.merge_requests.count - end - - def percent_complete - ((closed_items_count * 100) / total_items_count).abs - rescue ZeroDivisionError - 100 - end - - def expires_at - if due_date - if due_date.past? - "expired at #{due_date.stamp("Aug 21, 2011")}" - else - "expires at #{due_date.stamp("Aug 21, 2011")}" - end - end - end - - def can_be_closed? - active? && issues.opened.count.zero? - end - - def is_empty? - total_items_count.zero? - end - - def author_id - nil - end -end diff --git a/app/models/network/commit.rb b/app/models/network/commit.rb deleted file mode 100644 index 8417f200e366bd61f94374e6644d81e8f5afaa07..0000000000000000000000000000000000000000 --- a/app/models/network/commit.rb +++ /dev/null @@ -1,35 +0,0 @@ -module Network - class Commit - include ActionView::Helpers::TagHelper - - attr_accessor :time, :spaces, :parent_spaces - - def initialize(raw_commit) - @commit = raw_commit - @time = -1 - @spaces = [] - @parent_spaces = [] - end - - def method_missing(m, *args, &block) - @commit.send(m, *args, &block) - end - - def space - if @spaces.size > 0 - @spaces.first - else - 0 - end - end - - def parents(map) - @commit.parents.map do |p| - if map.include?(p.id) - map[p.id] - end - end - .compact - end - end -end diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb deleted file mode 100644 index f4e90125373dba51119c47fc2c822798e22400d5..0000000000000000000000000000000000000000 --- a/app/models/network/graph.rb +++ /dev/null @@ -1,267 +0,0 @@ -module Network - class Graph - attr_reader :days, :commits, :map, :notes, :repo - - def self.max_count - @max_count ||= 650 - end - - def initialize(project, ref, commit, filter_ref) - @project = project - @ref = ref - @commit = commit - @filter_ref = filter_ref - @repo = project.repository - - @commits = collect_commits - @days = index_commits - @notes = collect_notes - end - - protected - - def collect_notes - h = Hash.new(0) - @project.notes.where('noteable_type = ?' ,"Commit").group('notes.commit_id').select('notes.commit_id, count(notes.id) as note_count').each do |item| - h[item.commit_id] = item.note_count.to_i - end - h - end - - # Get commits from repository - # - def collect_commits - find_commits(count_to_display_commit_in_center).map do |commit| - # Decorate with app/model/network/commit.rb - Network::Commit.new(commit) - end - end - - # Method is adding time and space on the - # list of commits. As well as returns date list - # correlated with time set on commits. - # - # @return [Array] list of commit dates correlated with time on commits - def index_commits - days = [] - @map = {} - @reserved = {} - - @commits.each_with_index do |c,i| - c.time = i - days[i] = c.committed_date - @map[c.id] = c - @reserved[i] = [] - end - - commits_sort_by_ref.each do |commit| - place_chain(commit) - end - - # find parent spaces for not overlap lines - @commits.each do |c| - c.parent_spaces.concat(find_free_parent_spaces(c)) - end - - days - end - - # Skip count that the target commit is displayed in center. - def count_to_display_commit_in_center - offset = -1 - skip = 0 - while offset == -1 - tmp_commits = find_commits(skip) - if tmp_commits.size > 0 - index = tmp_commits.index do |c| - c.id == @commit.id - end - - if index - # Find the target commit - offset = index + skip - else - skip += self.class.max_count - end - else - # Can't find the target commit in the repo. - offset = 0 - end - end - - if self.class.max_count / 2 < offset then - # get max index that commit is displayed in the center. - offset - self.class.max_count / 2 - else - 0 - end - end - - def find_commits(skip = 0) - opts = { - max_count: self.class.max_count, - skip: skip - } - - opts[:ref] = @commit.id if @filter_ref - - @repo.find_commits(opts) - end - - def commits_sort_by_ref - @commits.sort do |a,b| - if include_ref?(a) - -1 - elsif include_ref?(b) - 1 - else - b.committed_date <=> a.committed_date - end - end - end - - def include_ref?(commit) - commit.ref_names(@repo).include?(@ref) - end - - def find_free_parent_spaces(commit) - spaces = [] - - commit.parents(@map).each do |parent| - range = commit.time..parent.time - - space = if commit.space >= parent.space then - find_free_parent_space(range, parent.space, -1, commit.space) - else - find_free_parent_space(range, commit.space, -1, parent.space) - end - - mark_reserved(range, space) - spaces << space - end - - spaces - end - - def find_free_parent_space(range, space_base, space_step, space_default) - if is_overlap?(range, space_default) then - find_free_space(range, space_step, space_base, space_default) - else - space_default - end - end - - def is_overlap?(range, overlap_space) - range.each do |i| - if i != range.first && - i != range.last && - @commits[i].spaces.include?(overlap_space) then - - return true; - end - end - - false - end - - # Add space mark on commit and its parents - # - # @param [::Commit] the commit object. - def place_chain(commit, parent_time = nil) - leaves = take_left_leaves(commit) - if leaves.empty? - return - end - - time_range = leaves.first.time..leaves.last.time - space_base = get_space_base(leaves) - space = find_free_space(time_range, 2, space_base) - leaves.each do |l| - l.spaces << space - end - - # and mark it as reserved - if parent_time.nil? - min_time = leaves.first.time - else - min_time = parent_time + 1 - end - - max_time = leaves.last.time - leaves.last.parents(@map).each do |parent| - if max_time < parent.time - max_time = parent.time - end - end - mark_reserved(min_time..max_time, space) - - # Visit branching chains - leaves.each do |l| - parents = l.parents(@map).select{|p| p.space.zero?} - for p in parents - place_chain(p, l.time) - end - end - end - - def get_space_base(leaves) - space_base = 1 - parents = leaves.last.parents(@map) - if parents.size > 0 - if parents.first.space > 0 - space_base = parents.first.space - end - end - space_base - end - - def mark_reserved(time_range, space) - for day in time_range - @reserved[day].push(space) - end - end - - def find_free_space(time_range, space_step, space_base = 1, space_default = nil) - space_default ||= space_base - - reserved = [] - for day in time_range - reserved.push(*@reserved[day]) - end - reserved.uniq! - - space = space_default - while reserved.include?(space) do - space += space_step - if space < space_base then - space_step *= -1 - space = space_base + space_step - end - end - - space - end - - # Takes most left subtree branch of commits - # which don't have space mark yet. - # - # @param [::Commit] the commit object. - # - # @return [Array] list of branch commits - def take_left_leaves(raw_commit) - commit = @map[raw_commit.id] - leaves = [] - leaves.push(commit) if commit.space.zero? - - while true - return leaves if commit.parents(@map).count.zero? - - commit = commit.parents(@map).first - - return leaves unless commit.space.zero? - - leaves.push(commit) - end - end - end -end diff --git a/app/models/note.rb b/app/models/note.rb deleted file mode 100644 index 2cf3fac2def6c0396c9c4e5823f99a6cf78db45e..0000000000000000000000000000000000000000 --- a/app/models/note.rb +++ /dev/null @@ -1,609 +0,0 @@ -# == Schema Information -# -# Table name: notes -# -# id :integer not null, primary key -# note :text -# noteable_type :string(255) -# author_id :integer -# created_at :datetime -# updated_at :datetime -# project_id :integer -# attachment :string(255) -# line_code :string(255) -# commit_id :string(255) -# noteable_id :integer -# system :boolean default(FALSE), not null -# st_diff :text -# - -require 'carrierwave/orm/activerecord' -require 'file_size_validator' - -class Note < ActiveRecord::Base - include Mentionable - include Gitlab::CurrentSettings - - default_value_for :system, false - - attr_mentionable :note - - belongs_to :project - belongs_to :noteable, polymorphic: true - belongs_to :author, class_name: "User" - - delegate :name, to: :project, prefix: true - delegate :name, :email, to: :author, prefix: true - - validates :note, :project, presence: true - validates :line_code, format: { with: /\A[a-z0-9]+_\d+_\d+\Z/ }, allow_blank: true - # Attachments are deprecated and are handled by Markdown uploader - validates :attachment, file_size: { maximum: :max_attachment_size } - - validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' } - validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' } - - mount_uploader :attachment, AttachmentUploader - - # Scopes - scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) } - scope :inline, ->{ where("line_code IS NOT NULL") } - scope :not_inline, ->{ where(line_code: [nil, '']) } - scope :system, ->{ where(system: true) } - scope :user, ->{ where(system: false) } - scope :common, ->{ where(noteable_type: ["", nil]) } - scope :fresh, ->{ order(created_at: :asc, id: :asc) } - scope :inc_author_project, ->{ includes(:project, :author) } - scope :inc_author, ->{ includes(:author) } - - serialize :st_diff - before_create :set_diff, if: ->(n) { n.line_code.present? } - after_update :set_references - - class << self - def create_status_change_note(noteable, project, author, status, source) - body = "Status changed to #{status}#{' by ' + source.gfm_reference if source}" - - create( - noteable: noteable, - project: project, - author: author, - note: body, - system: true - ) - end - - # +noteable+ was referenced from +mentioner+, by including GFM in either - # +mentioner+'s description or an associated Note. - # Create a system Note associated with +noteable+ with a GFM back-reference - # to +mentioner+. - def create_cross_reference_note(noteable, mentioner, author, project) - gfm_reference = mentioner_gfm_ref(noteable, mentioner, project) - - note_options = { - project: project, - author: author, - note: cross_reference_note_content(gfm_reference), - system: true - } - - if noteable.kind_of?(Commit) - note_options.merge!(noteable_type: 'Commit', commit_id: noteable.id) - else - note_options.merge!(noteable: noteable) - end - - create(note_options) unless cross_reference_disallowed?(noteable, mentioner) - end - - def create_milestone_change_note(noteable, project, author, milestone) - body = if milestone.nil? - 'Milestone removed' - else - "Milestone changed to #{milestone.title}" - end - - create( - noteable: noteable, - project: project, - author: author, - note: body, - system: true - ) - end - - def create_assignee_change_note(noteable, project, author, assignee) - body = assignee.nil? ? 'Assignee removed' : "Reassigned to @#{assignee.username}" - - create({ - noteable: noteable, - project: project, - author: author, - note: body, - system: true - }) - end - - def create_labels_change_note(noteable, project, author, added_labels, removed_labels) - labels_count = added_labels.count + removed_labels.count - added_labels = added_labels.map{ |label| "~#{label.id}" }.join(' ') - removed_labels = removed_labels.map{ |label| "~#{label.id}" }.join(' ') - message = '' - - if added_labels.present? - message << "added #{added_labels}" - end - - if added_labels.present? && removed_labels.present? - message << ' and ' - end - - if removed_labels.present? - message << "removed #{removed_labels}" - end - - message << ' ' << 'label'.pluralize(labels_count) - body = "#{message.capitalize}" - - create( - noteable: noteable, - project: project, - author: author, - note: body, - system: true - ) - end - - def create_new_commits_note(merge_request, project, author, new_commits, existing_commits = [], oldrev = nil) - total_count = new_commits.length + existing_commits.length - commits_text = ActionController::Base.helpers.pluralize(total_count, 'commit') - body = "Added #{commits_text}:\n\n" - - if existing_commits.length > 0 - commit_ids = - if existing_commits.length == 1 - existing_commits.first.short_id - else - if oldrev - "#{Commit.truncate_sha(oldrev)}...#{existing_commits.last.short_id}" - else - "#{existing_commits.first.short_id}..#{existing_commits.last.short_id}" - end - end - - commits_text = ActionController::Base.helpers.pluralize(existing_commits.length, 'commit') - - branch = - if merge_request.for_fork? - "#{merge_request.target_project_namespace}:#{merge_request.target_branch}" - else - merge_request.target_branch - end - - message = "* #{commit_ids} - #{commits_text} from branch `#{branch}`" - body << message - body << "\n" - end - - new_commits.each do |commit| - message = "* #{commit.short_id} - #{commit.title}" - body << message - body << "\n" - end - - create( - noteable: merge_request, - project: project, - author: author, - note: body, - system: true - ) - end - - def discussions_from_notes(notes) - discussion_ids = [] - discussions = [] - - notes.each do |note| - next if discussion_ids.include?(note.discussion_id) - - # don't group notes for the main target - if !note.for_diff_line? && note.noteable_type == "MergeRequest" - discussions << [note] - else - discussions << notes.select do |other_note| - note.discussion_id == other_note.discussion_id - end - discussion_ids << note.discussion_id - end - end - - discussions - end - - def build_discussion_id(type, id, line_code) - [:discussion, type.try(:underscore), id, line_code].join("-").to_sym - end - - # Determine if cross reference note should be created. - # eg. mentioning a commit in MR comments which exists inside a MR - # should not create "mentioned in" note. - def cross_reference_disallowed?(noteable, mentioner) - if mentioner.kind_of?(MergeRequest) - mentioner.commits.map(&:id).include? noteable.id - end - end - - # Determine whether or not a cross-reference note already exists. - def cross_reference_exists?(noteable, mentioner) - gfm_reference = mentioner_gfm_ref(noteable, mentioner) - notes = if noteable.is_a?(Commit) - where(commit_id: noteable.id) - else - where(noteable_id: noteable.id) - end - - notes.where('note like ?', cross_reference_note_pattern(gfm_reference)). - system.any? - end - - def search(query) - where("note like :query", query: "%#{query}%") - end - - def cross_reference_note_prefix - 'mentioned in ' - end - - private - - def cross_reference_note_content(gfm_reference) - cross_reference_note_prefix + "#{gfm_reference}" - end - - def cross_reference_note_pattern(gfm_reference) - # Older cross reference notes contained underscores for emphasis - "%" + cross_reference_note_content(gfm_reference) + "%" - end - - # Prepend the mentioner's namespaced project path to the GFM reference for - # cross-project references. For same-project references, return the - # unmodified GFM reference. - def mentioner_gfm_ref(noteable, mentioner, project = nil) - if mentioner.is_a?(Commit) - if project.nil? - return mentioner.gfm_reference.sub('commit ', 'commit %') - else - mentioning_project = project - end - else - mentioning_project = mentioner.project - end - - noteable_project_id = noteable_project_id(noteable, mentioning_project) - - full_gfm_reference(mentioning_project, noteable_project_id, mentioner) - end - - # Return the ID of the project that +noteable+ belongs to, or nil if - # +noteable+ is a commit and is not part of the project that owns - # +mentioner+. - def noteable_project_id(noteable, mentioning_project) - if noteable.is_a?(Commit) - if mentioning_project.repository.commit(noteable.id) - # The noteable commit belongs to the mentioner's project - mentioning_project.id - else - nil - end - else - noteable.project.id - end - end - - # Return the +mentioner+ GFM reference. If the mentioner and noteable - # projects are not the same, add the mentioning project's path to the - # returned value. - def full_gfm_reference(mentioning_project, noteable_project_id, mentioner) - if mentioning_project.id == noteable_project_id - mentioner.gfm_reference - else - if mentioner.is_a?(Commit) - mentioner.gfm_reference.sub( - /(commit )/, - "\\1#{mentioning_project.path_with_namespace}@" - ) - else - mentioner.gfm_reference.sub( - /(issue |merge request )/, - "\\1#{mentioning_project.path_with_namespace}" - ) - end - end - end - end - - def max_attachment_size - current_application_settings.max_attachment_size.megabytes.to_i - end - - def commit_author - @commit_author ||= - project.team.users.find_by(email: noteable.author_email) || - project.team.users.find_by(name: noteable.author_name) - rescue - nil - end - - def cross_reference? - note.start_with?(self.class.cross_reference_note_prefix) - end - - def find_diff - return nil unless noteable && noteable.diffs.present? - - @diff ||= noteable.diffs.find do |d| - Digest::SHA1.hexdigest(d.new_path) == diff_file_index if d.new_path - end - end - - def hook_attrs - attributes - end - - def set_diff - # First lets find notes with same diff - # before iterating over all mr diffs - diff = diff_for_line_code unless for_merge_request? - diff ||= find_diff - - self.st_diff = diff.to_hash if diff - end - - def diff - @diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map) - end - - def diff_for_line_code - Note.where(noteable_id: noteable_id, noteable_type: noteable_type, line_code: line_code).last.try(:diff) - end - - # Check if such line of code exists in merge request diff - # If exists - its active discussion - # If not - its outdated diff - def active? - return true unless self.diff - return false unless noteable - - noteable.diffs.each do |mr_diff| - next unless mr_diff.new_path == self.diff.new_path - - lines = Gitlab::Diff::Parser.new.parse(mr_diff.diff.lines.to_a) - - lines.each do |line| - if line.text == diff_line - return true - end - end - end - - false - end - - def outdated? - !active? - end - - def diff_file_index - line_code.split('_')[0] if line_code - end - - def diff_file_name - diff.new_path if diff - end - - def file_path - if diff.new_path.present? - diff.new_path - elsif diff.old_path.present? - diff.old_path - end - end - - def diff_old_line - line_code.split('_')[1].to_i if line_code - end - - def diff_new_line - line_code.split('_')[2].to_i if line_code - end - - def generate_line_code(line) - Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos) - end - - def diff_line - return @diff_line if @diff_line - - if diff - diff_lines.each do |line| - if generate_line_code(line) == self.line_code - @diff_line = line.text - end - end - end - - @diff_line - end - - def diff_line_type - return @diff_line_type if @diff_line_type - - if diff - diff_lines.each do |line| - if generate_line_code(line) == self.line_code - @diff_line_type = line.type - end - end - end - - @diff_line_type - end - - def truncated_diff_lines - max_number_of_lines = 16 - prev_match_line = nil - prev_lines = [] - - diff_lines.each do |line| - if line.type == "match" - prev_lines.clear - prev_match_line = line - else - prev_lines << line - - break if generate_line_code(line) == self.line_code - - prev_lines.shift if prev_lines.length >= max_number_of_lines - end - end - - prev_lines - end - - def diff_lines - @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.lines.to_a) - end - - def discussion_id - @discussion_id ||= Note.build_discussion_id(noteable_type, noteable_id || commit_id, line_code) - end - - # Returns true if this is a downvote note, - # otherwise false is returned - def downvote? - votable? && (note.start_with?('-1') || - note.start_with?(':-1:') || - note.start_with?(':thumbsdown:') || - note.start_with?(':thumbs_down_sign:') - ) - end - - def for_commit? - noteable_type == "Commit" - end - - def for_commit_diff_line? - for_commit? && for_diff_line? - end - - def for_diff_line? - line_code.present? - end - - def for_issue? - noteable_type == "Issue" - end - - def for_merge_request? - noteable_type == "MergeRequest" - end - - def for_merge_request_diff_line? - for_merge_request? && for_diff_line? - end - - def for_project_snippet? - noteable_type == "Snippet" - end - - # override to return commits, which are not active record - def noteable - if for_commit? - project.repository.commit(commit_id) - else - super - end - # Temp fix to prevent app crash - # if note commit id doesn't exist - rescue - nil - end - - # Returns true if this is an upvote note, - # otherwise false is returned - def upvote? - votable? && (note.start_with?('+1') || - note.start_with?(':+1:') || - note.start_with?(':thumbsup:') || - note.start_with?(':thumbs_up_sign:') - ) - end - - def superceded?(notes) - return false unless vote? - - notes.each do |note| - next if note == self - - if note.vote? && - self[:author_id] == note[:author_id] && - self[:created_at] <= note[:created_at] - return true - end - end - - false - end - - def vote? - upvote? || downvote? - end - - def votable? - for_issue? || (for_merge_request? && !for_diff_line?) - end - - # Mentionable override. - def gfm_reference - noteable.gfm_reference - end - - # Mentionable override. - def local_reference - noteable - end - - def noteable_type_name - if noteable_type.present? - noteable_type.downcase - end - end - - # FIXME: Hack for polymorphic associations with STI - # For more information visit http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations - def noteable_type=(sType) - super(sType.to_s.classify.constantize.base_class.to_s) - end - - # Reset notes events cache - # - # Since we do cache @event we need to reset cache in special cases: - # * when a note is updated - # * when a note is removed - # Events cache stored like events/23-20130109142513. - # The cache key includes updated_at timestamp. - # Thus it will automatically generate a new fragment - # when the event is updated because the key changes. - def reset_events_cache - Event.reset_event_cache_for(self) - end - - def set_references - notice_added_references(project, author) - end - - def editable? - !read_attribute(:system) - end -end diff --git a/app/models/notification.rb b/app/models/notification.rb deleted file mode 100644 index 1395274173d4d18609167b6b9f6ed12abc133076..0000000000000000000000000000000000000000 --- a/app/models/notification.rb +++ /dev/null @@ -1,60 +0,0 @@ -class Notification - # - # Notification levels - # - N_DISABLED = 0 - N_PARTICIPATING = 1 - N_WATCH = 2 - N_GLOBAL = 3 - N_MENTION = 4 - - attr_accessor :target - - class << self - def notification_levels - [N_DISABLED, N_PARTICIPATING, N_WATCH, N_MENTION] - end - - def options_with_labels - { - disabled: N_DISABLED, - participating: N_PARTICIPATING, - watch: N_WATCH, - mention: N_MENTION, - global: N_GLOBAL - } - end - - def project_notification_levels - [N_DISABLED, N_PARTICIPATING, N_WATCH, N_GLOBAL, N_MENTION] - end - end - - def initialize(target) - @target = target - end - - def disabled? - target.notification_level == N_DISABLED - end - - def participating? - target.notification_level == N_PARTICIPATING - end - - def watch? - target.notification_level == N_WATCH - end - - def global? - target.notification_level == N_GLOBAL - end - - def mention? - target.notification_level == N_MENTION - end - - def level - target.notification_level - end -end diff --git a/app/models/personal_snippet.rb b/app/models/personal_snippet.rb deleted file mode 100644 index 9cee3b70cb3ecf2f271320bfbf5ab57eceb9cc02..0000000000000000000000000000000000000000 --- a/app/models/personal_snippet.rb +++ /dev/null @@ -1,19 +0,0 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string(255) -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string(255) -# expires_at :datetime -# type :string(255) -# visibility_level :integer default(0), not null -# - -class PersonalSnippet < Snippet -end diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb deleted file mode 100644 index e6e16058d41bd7223dadb698513a5f7c57bd8b17..0000000000000000000000000000000000000000 --- a/app/models/project_services/asana_service.rb +++ /dev/null @@ -1,127 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# -require 'asana' - -class AsanaService < Service - prop_accessor :api_key, :restrict_to_branch - validates :api_key, presence: true, if: :activated? - - def title - 'Asana' - end - - def description - 'Asana - Teamwork without email' - end - - def help - 'This service adds commit messages as comments to Asana tasks. -Once enabled, commit messages are checked for Asana task URLs -(for example, `https://app.asana.com/0/123456/987654`) or task IDs -starting with # (for example, `#987654`). Every task ID found will -get the commit comment added to it. - -You can also close a task with a message containing: `fix #123456`. - -You can find your Api Keys here: -http://developer.asana.com/documentation/#api_keys' - end - - def to_param - 'asana' - end - - def fields - [ - { - type: 'text', - name: 'api_key', - placeholder: 'User API token. User must have access to task, -all comments will be attributed to this user.' - }, - { - type: 'text', - name: 'restrict_to_branch', - placeholder: 'Comma-separated list of branches which will be -automatically inspected. Leave blank to include all branches.' - } - ] - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - Asana.configure do |client| - client.api_key = api_key - end - - user = data[:user_name] - branch = Gitlab::Git.ref_name(data[:ref]) - - branch_restriction = restrict_to_branch.to_s - - # check the branch restriction is poplulated and branch is not included - if branch_restriction.length > 0 && branch_restriction.index(branch).nil? - return - end - - project_name = project.name_with_namespace - push_msg = user + ' pushed to branch ' + branch + ' of ' + project_name - - data[:commits].each do |commit| - check_commit(' ( ' + commit[:url] + ' ): ' + commit[:message], push_msg) - end - end - - def check_commit(message, push_msg) - task_list = [] - close_list = [] - - message.split("\n").each do |line| - # look for a task ID or a full Asana url - task_list.concat(line.scan(/#(\d+)/)) - task_list.concat(line.scan(/https:\/\/app\.asana\.com\/\d+\/\d+\/(\d+)/)) - # look for a word starting with 'fix' followed by a task ID - close_list.concat(line.scan(/(fix\w*)\W*#(\d+)/i)) - end - - # post commit to every taskid found - task_list.each do |taskid| - task = Asana::Task.find(taskid[0]) - - if task - task.create_story(text: push_msg + ' ' + message) - end - end - - # close all tasks that had 'fix(ed/es/ing) #:id' in them - close_list.each do |taskid| - task = Asana::Task.find(taskid.last) - - if task - task.modify(completed: true) - end - end - end -end diff --git a/app/models/project_services/assembla_service.rb b/app/models/project_services/assembla_service.rb deleted file mode 100644 index fb7e0c0fb0d1580c5b36217e6f5f44b9e7f3b289..0000000000000000000000000000000000000000 --- a/app/models/project_services/assembla_service.rb +++ /dev/null @@ -1,56 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class AssemblaService < Service - include HTTParty - - prop_accessor :token, :subdomain - validates :token, presence: true, if: :activated? - - def title - 'Assembla' - end - - def description - 'Project Management Software (Source Commits Endpoint)' - end - - def to_param - 'assembla' - end - - def fields - [ - { type: 'text', name: 'token', placeholder: '' }, - { type: 'text', name: 'subdomain', placeholder: '' } - ] - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - url = "https://atlas.assembla.com/spaces/#{subdomain}/github_tool?secret_key=#{token}" - AssemblaService.post(url, body: { payload: data }.to_json, headers: { 'Content-Type' => 'application/json' }) - end -end diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb deleted file mode 100644 index d8aedbd2ab48c86726ccd7c0e472af2133859971..0000000000000000000000000000000000000000 --- a/app/models/project_services/bamboo_service.rb +++ /dev/null @@ -1,137 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class BambooService < CiService - include HTTParty - - prop_accessor :bamboo_url, :build_key, :username, :password - - validates :bamboo_url, - presence: true, - format: { with: /\A#{URI.regexp}\z/ }, - if: :activated? - validates :build_key, presence: true, if: :activated? - validates :username, - presence: true, - if: ->(service) { service.password? }, - if: :activated? - validates :password, - presence: true, - if: ->(service) { service.username? }, - if: :activated? - - attr_accessor :response - - after_save :compose_service_hook, if: :activated? - - def compose_service_hook - hook = service_hook || build_service_hook - hook.save - end - - def title - 'Atlassian Bamboo CI' - end - - def description - 'A continuous integration and build server' - end - - def help - 'You must set up automatic revision labeling and a repository trigger in Bamboo.' - end - - def to_param - 'bamboo' - end - - def fields - [ - { type: 'text', name: 'bamboo_url', - placeholder: 'Bamboo root URL like https://bamboo.example.com' }, - { type: 'text', name: 'build_key', - placeholder: 'Bamboo build plan key like KEY' }, - { type: 'text', name: 'username', - placeholder: 'A user with API access, if applicable' }, - { type: 'password', name: 'password' }, - ] - end - - def supported_events - %w(push) - end - - def build_info(sha) - url = URI.parse("#{bamboo_url}/rest/api/latest/result?label=#{sha}") - - if username.blank? && password.blank? - @response = HTTParty.get(parsed_url.to_s, verify: false) - else - get_url = "#{url}&os_authType=basic" - auth = { - username: username, - password: password, - } - @response = HTTParty.get(get_url, verify: false, basic_auth: auth) - end - end - - def build_page(sha, ref) - build_info(sha) if @response.nil? || !@response.code - - if @response.code != 200 || @response['results']['results']['size'] == '0' - # If actual build link can't be determined, send user to build summary page. - "#{bamboo_url}/browse/#{build_key}" - else - # If actual build link is available, go to build result page. - result_key = @response['results']['results']['result']['planResultKey']['key'] - "#{bamboo_url}/browse/#{result_key}" - end - end - - def commit_status(sha, ref) - build_info(sha) if @response.nil? || !@response.code - return :error unless @response.code == 200 || @response.code == 404 - - status = if @response.code == 404 || @response['results']['results']['size'] == '0' - 'Pending' - else - @response['results']['results']['result']['buildState'] - end - - if status.include?('Success') - 'success' - elsif status.include?('Failed') - 'failed' - elsif status.include?('Pending') - 'pending' - else - :error - end - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - # Bamboo requires a GET and does not take any data. - self.class.get("#{bamboo_url}/updateAndBuild.action?buildKey=#{build_key}", - verify: false) - end -end diff --git a/app/models/project_services/buildkite_service.rb b/app/models/project_services/buildkite_service.rb deleted file mode 100644 index a714bc82246d778742b7497d657750b8b79272eb..0000000000000000000000000000000000000000 --- a/app/models/project_services/buildkite_service.rb +++ /dev/null @@ -1,135 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -require "addressable/uri" - -class BuildkiteService < CiService - ENDPOINT = "https://buildkite.com" - - prop_accessor :project_url, :token - - validates :project_url, presence: true, if: :activated? - validates :token, presence: true, if: :activated? - - after_save :compose_service_hook, if: :activated? - - def webhook_url - "#{buildkite_endpoint('webhook')}/deliver/#{webhook_token}" - end - - def compose_service_hook - hook = service_hook || build_service_hook - hook.url = webhook_url - hook.save - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - service_hook.execute(data) - end - - def commit_status(sha, ref) - response = HTTParty.get(commit_status_path(sha), verify: false) - - if response.code == 200 && response['status'] - response['status'] - else - :error - end - end - - def commit_status_path(sha) - "#{buildkite_endpoint('gitlab')}/status/#{status_token}.json?commit=#{sha}" - end - - def build_page(sha, ref) - "#{project_url}/builds?commit=#{sha}" - end - - def builds_path - "#{project_url}/builds?branch=#{project.default_branch}" - end - - def status_img_path - "#{buildkite_endpoint('badge')}/#{status_token}.svg" - end - - def title - 'Buildkite' - end - - def description - 'Continuous integration and deployments' - end - - def to_param - 'buildkite' - end - - def fields - [ - { type: 'text', - name: 'token', - placeholder: 'Buildkite project GitLab token' }, - - { type: 'text', - name: 'project_url', - placeholder: "#{ENDPOINT}/example/project" } - ] - end - - private - - def webhook_token - token_parts.first - end - - def status_token - token_parts.second - end - - def token_parts - if token.present? - token.split(':') - else - [] - end - end - - def buildkite_endpoint(subdomain = nil) - if subdomain.present? - uri = Addressable::URI.parse(ENDPOINT) - new_endpoint = "#{uri.scheme || 'http'}://#{subdomain}.#{uri.host}" - - if uri.port.present? - "#{new_endpoint}:#{uri.port}" - else - new_endpoint - end - else - ENDPOINT - end - end -end diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb deleted file mode 100644 index e591afdda6448e1502bb075b2a90a15cec9cb119..0000000000000000000000000000000000000000 --- a/app/models/project_services/campfire_service.rb +++ /dev/null @@ -1,86 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class CampfireService < Service - prop_accessor :token, :subdomain, :room - validates :token, presence: true, if: :activated? - - def title - 'Campfire' - end - - def description - 'Simple web-based real-time group chat' - end - - def to_param - 'campfire' - end - - def fields - [ - { type: 'text', name: 'token', placeholder: '' }, - { type: 'text', name: 'subdomain', placeholder: '' }, - { type: 'text', name: 'room', placeholder: '' } - ] - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - room = gate.find_room_by_name(self.room) - return true unless room - - message = build_message(data) - - room.speak(message) - end - - private - - def gate - @gate ||= Tinder::Campfire.new(subdomain, token: token) - end - - def build_message(push) - ref = Gitlab::Git.ref_name(push[:ref]) - before = push[:before] - after = push[:after] - - message = "" - message << "[#{project.name_with_namespace}] " - message << "#{push[:user_name]} " - - if Gitlab::Git.blank_ref?(before) - message << "pushed new branch #{ref} \n" - elsif Gitlab::Git.blank_ref?(after) - message << "removed branch #{ref} \n" - else - message << "pushed #{push[:total_commits_count]} commits to #{ref}. " - message << "#{project.web_url}/compare/#{before}...#{after}" - end - - message - end -end diff --git a/app/models/project_services/ci_service.rb b/app/models/project_services/ci_service.rb deleted file mode 100644 index 1a36e439245c1d7ef3cba67f84e2d666074431da..0000000000000000000000000000000000000000 --- a/app/models/project_services/ci_service.rb +++ /dev/null @@ -1,57 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -# Base class for CI services -# List methods you need to implement to get your CI service -# working with GitLab Merge Requests -class CiService < Service - def category - :ci - end - - def supported_events - %w(push) - end - - # Return complete url to build page - # - # Ex. - # http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c - # - def build_page(sha, ref) - # implement inside child - end - - # Return string with build status or :error symbol - # - # Allowed states: 'success', 'failed', 'running', 'pending' - # - # - # Ex. - # @service.commit_status('13be4ac') - # # => 'success' - # - # @service.commit_status('2abe4ac') - # # => 'running' - # - # - def commit_status(sha, ref) - # implement inside child - end -end diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb deleted file mode 100644 index 8d25f6278709b42cd768127beab4af769f416669..0000000000000000000000000000000000000000 --- a/app/models/project_services/custom_issue_tracker_service.rb +++ /dev/null @@ -1,57 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -class CustomIssueTrackerService < IssueTrackerService - - prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url - - def title - if self.properties && self.properties['title'].present? - self.properties['title'] - else - 'Custom Issue Tracker' - end - end - - def description - if self.properties && self.properties['description'].present? - self.properties['description'] - else - 'Custom issue tracker' - end - end - - def to_param - 'custom_issue_tracker' - end - - def fields - [ - { type: 'text', name: 'title', placeholder: title }, - { type: 'text', name: 'description', placeholder: description }, - { type: 'text', name: 'project_url', placeholder: 'Project url' }, - { type: 'text', name: 'issues_url', placeholder: 'Issue url' }, - { type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' } - ] - end - - def initialize_properties - self.properties = {} if properties.nil? - end -end diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb deleted file mode 100644 index 6f6e5950aab3575b00cc53f9030e4946003dd46b..0000000000000000000000000000000000000000 --- a/app/models/project_services/emails_on_push_service.rb +++ /dev/null @@ -1,72 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -class EmailsOnPushService < Service - prop_accessor :send_from_committer_email - prop_accessor :disable_diffs - prop_accessor :recipients - validates :recipients, presence: true, if: :activated? - - def title - 'Emails on push' - end - - def description - 'Email the commits and diff of each push to a list of recipients.' - end - - def to_param - 'emails_on_push' - end - - def supported_events - %w(push tag_push) - end - - def execute(push_data) - return unless supported_events.include?(push_data[:object_kind]) - - EmailsOnPushWorker.perform_async( - project_id, - recipients, - push_data, - send_from_committer_email: send_from_committer_email?, - disable_diffs: disable_diffs? - ) - end - - def send_from_committer_email? - self.send_from_committer_email == "1" - end - - def disable_diffs? - self.disable_diffs == "1" - end - - def fields - domains = Notify.allowed_email_domains.map { |domain| "user@#{domain}" }.join(", ") - [ - { type: 'checkbox', name: 'send_from_committer_email', title: "Send from committer", - help: "Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. #{domains})." }, - { type: 'checkbox', name: 'disable_diffs', title: "Disable code diffs", - help: "Don't include possibly sensitive code diffs in notification body." }, - { type: 'textarea', name: 'recipients', placeholder: 'Emails separated by whitespace' }, - ] - end -end diff --git a/app/models/project_services/external_wiki_service.rb b/app/models/project_services/external_wiki_service.rb deleted file mode 100644 index a199d0e86f2ce43f94fbff1516761856ed729690..0000000000000000000000000000000000000000 --- a/app/models/project_services/external_wiki_service.rb +++ /dev/null @@ -1,48 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# - -class ExternalWikiService < Service - include HTTParty - - prop_accessor :external_wiki_url - validates :external_wiki_url, - presence: true, - format: { with: /\A#{URI.regexp}\z/ }, - if: :activated? - - def title - 'External Wiki' - end - - def description - 'Replaces the link to the internal wiki with a link to an external wiki.' - end - - def to_param - 'external_wiki' - end - - def fields - [ - { type: 'text', name: 'external_wiki_url', placeholder: 'The URL of the external Wiki' }, - ] - end - - def execute(_data) - @response = HTTParty.get(properties['external_wiki_url'], verify: true) rescue nil - if @response !=200 - nil - end - end -end diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb deleted file mode 100644 index 99e361dd6ed18361d59ae4fb5b54fe76f0ae32e3..0000000000000000000000000000000000000000 --- a/app/models/project_services/flowdock_service.rb +++ /dev/null @@ -1,62 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require "flowdock-git-hook" - -class FlowdockService < Service - prop_accessor :token - validates :token, presence: true, if: :activated? - - def title - 'Flowdock' - end - - def description - 'Flowdock is a collaboration web app for technical teams.' - end - - def to_param - 'flowdock' - end - - def fields - [ - { type: 'text', name: 'token', placeholder: '' } - ] - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - Flowdock::Git.post( - data[:ref], - data[:before], - data[:after], - token: token, - repo: project.repository.path_to_repo, - repo_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}", - commit_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/%s", - diff_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/compare/%s...%s", - ) - end -end diff --git a/app/models/project_services/gemnasium_service.rb b/app/models/project_services/gemnasium_service.rb deleted file mode 100644 index 4e75bdfc953eec9ee220cf00e505b07292f44dc9..0000000000000000000000000000000000000000 --- a/app/models/project_services/gemnasium_service.rb +++ /dev/null @@ -1,61 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require "gemnasium/gitlab_service" - -class GemnasiumService < Service - prop_accessor :token, :api_key - validates :token, :api_key, presence: true, if: :activated? - - def title - 'Gemnasium' - end - - def description - 'Gemnasium monitors your project dependencies and alerts you about updates and security vulnerabilities.' - end - - def to_param - 'gemnasium' - end - - def fields - [ - { type: 'text', name: 'api_key', placeholder: 'Your personal API KEY on gemnasium.com ' }, - { type: 'text', name: 'token', placeholder: 'The project\'s slug on gemnasium.com' } - ] - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - Gemnasium::GitlabService.execute( - ref: data[:ref], - before: data[:before], - after: data[:after], - token: token, - api_key: api_key, - repo: project.repository.path_to_repo - ) - end -end diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb deleted file mode 100644 index 0f9838a575ddc7e4ee54a2d48d3159df95af24d9..0000000000000000000000000000000000000000 --- a/app/models/project_services/gitlab_ci_service.rb +++ /dev/null @@ -1,128 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -class GitlabCiService < CiService - API_PREFIX = "api/v1" - - prop_accessor :project_url, :token - validates :project_url, presence: true, if: :activated? - validates :token, presence: true, if: :activated? - - after_save :compose_service_hook, if: :activated? - - def compose_service_hook - hook = service_hook || build_service_hook - hook.url = [project_url, "/build", "?token=#{token}"].join("") - hook.save - end - - def supported_events - %w(push tag_push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - service_hook.execute(data) - end - - def commit_status_path(sha, ref) - project_url + "/refs/#{ref}/commits/#{sha}/status.json?token=#{token}" - end - - def get_ci_build(sha, ref) - @ci_builds ||= {} - @ci_builds[sha] ||= HTTParty.get(commit_status_path(sha, ref), verify: false) - end - - def commit_status(sha, ref) - response = get_ci_build(sha, ref) - - if response.code == 200 and response["status"] - response["status"] - else - :error - end - end - - def fork_registration(new_project, private_token) - params = { - id: new_project.id, - name_with_namespace: new_project.name_with_namespace, - web_url: new_project.web_url, - default_branch: new_project.default_branch, - ssh_url_to_repo: new_project.ssh_url_to_repo - } - - HTTParty.post( - fork_registration_path, - body: { - project_id: project.id, - project_token: token, - private_token: private_token, - data: params }, - verify: false - ) - end - - def commit_coverage(sha, ref) - response = get_ci_build(sha, ref) - - if response.code == 200 and response["coverage"] - response["coverage"] - end - end - - def build_page(sha, ref) - project_url + "/refs/#{ref}/commits/#{sha}" - end - - def builds_path - project_url + "?ref=" + project.default_branch - end - - def status_img_path - project_url + "/status.png?ref=" + project.default_branch - end - - def title - 'GitLab CI' - end - - def description - 'Continuous integration server from GitLab' - end - - def to_param - 'gitlab_ci' - end - - def fields - [ - { type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' }, - { type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' } - ] - end - - private - - def fork_registration_path - project_url.sub(/projects\/\d*/, "#{API_PREFIX}/forks") - end -end diff --git a/app/models/project_services/gitlab_issue_tracker_service.rb b/app/models/project_services/gitlab_issue_tracker_service.rb deleted file mode 100644 index 5f0553f3b0b8fae06ce232249ba872c7bb823206..0000000000000000000000000000000000000000 --- a/app/models/project_services/gitlab_issue_tracker_service.rb +++ /dev/null @@ -1,62 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class GitlabIssueTrackerService < IssueTrackerService - include Rails.application.routes.url_helpers - - default_url_options[:host] = Gitlab.config.gitlab.host - default_url_options[:protocol] = Gitlab.config.gitlab.protocol - default_url_options[:port] = Gitlab.config.gitlab.port unless Gitlab.config.gitlab_on_standard_port? - default_url_options[:script_name] = Gitlab.config.gitlab.relative_url_root - - prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url - - def default? - true - end - - def to_param - 'gitlab' - end - - def project_url - namespace_project_issues_url(project.namespace, project) - end - - def new_issue_url - new_namespace_project_issue_url(namespace_id: project.namespace, project_id: project) - end - - def issue_url(iid) - namespace_project_issue_url(namespace_id: project.namespace, project_id: project, id: iid) - end - - def project_path - namespace_project_issues_path(project.namespace, project) - end - - def new_issue_path - new_namespace_project_issue_path(namespace_id: project.namespace, project_id: project) - end - - def issue_path(iid) - namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: iid) - end -end diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb deleted file mode 100644 index d264a56ebdf496582c6861139b1eb8a789195a1f..0000000000000000000000000000000000000000 --- a/app/models/project_services/hipchat_service.rb +++ /dev/null @@ -1,238 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -class HipchatService < Service - MAX_COMMITS = 3 - - prop_accessor :token, :room, :server - validates :token, presence: true, if: :activated? - - def title - 'HipChat' - end - - def description - 'Private group chat and IM' - end - - def to_param - 'hipchat' - end - - def fields - [ - { type: 'text', name: 'token', placeholder: 'Room token' }, - { type: 'text', name: 'room', placeholder: 'Room name or ID' }, - { type: 'text', name: 'server', - placeholder: 'Leave blank for default. https://hipchat.example.com' } - ] - end - - def supported_events - %w(push issue merge_request note tag_push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - gate[room].send('GitLab', create_message(data)) - end - - private - - def gate - options = { api_version: 'v2' } - options[:server_url] = server unless server.blank? - @gate ||= HipChat::Client.new(token, options) - end - - def create_message(data) - object_kind = data[:object_kind] - - message = \ - case object_kind - when "push", "tag_push" - create_push_message(data) - when "issue" - create_issue_message(data) unless is_update?(data) - when "merge_request" - create_merge_request_message(data) unless is_update?(data) - when "note" - create_note_message(data) - end - end - - def create_push_message(push) - ref_type = Gitlab::Git.tag_ref?(push[:ref]) ? 'tag' : 'branch' - ref = Gitlab::Git.ref_name(push[:ref]) - - before = push[:before] - after = push[:after] - - message = "" - message << "#{push[:user_name]} " - if Gitlab::Git.blank_ref?(before) - message << "pushed new #{ref_type} #{ref}"\ - " to #{project_link}\n" - elsif Gitlab::Git.blank_ref?(after) - message << "removed #{ref_type} #{ref} from #{project_name} \n" - else - message << "pushed to #{ref_type} #{ref} " - message << "of #{project.name_with_namespace.gsub!(/\s/,'')} " - message << "(Compare changes)" - - push[:commits].take(MAX_COMMITS).each do |commit| - message << "
    - #{commit[:message].lines.first} (#{commit[:id][0..5]})" - end - - if push[:commits].count > MAX_COMMITS - message << "
    ... #{push[:commits].count - MAX_COMMITS} more commits" - end - end - - message - end - - def format_body(body) - if body - body = body.truncate(200, separator: ' ', omission: '...') - end - - "

    #{body}
    " - end - - def create_issue_message(data) - user_name = data[:user][:name] - - obj_attr = data[:object_attributes] - obj_attr = HashWithIndifferentAccess.new(obj_attr) - title = obj_attr[:title] - state = obj_attr[:state] - issue_iid = obj_attr[:iid] - issue_url = obj_attr[:url] - description = obj_attr[:description] - - issue_link = "issue ##{issue_iid}" - message = "#{user_name} #{state} #{issue_link} in #{project_link}: #{title}" - - if description - description = format_body(description) - message << description - end - - message - end - - def create_merge_request_message(data) - user_name = data[:user][:name] - - obj_attr = data[:object_attributes] - obj_attr = HashWithIndifferentAccess.new(obj_attr) - merge_request_id = obj_attr[:iid] - source_branch = obj_attr[:source_branch] - target_branch = obj_attr[:target_branch] - state = obj_attr[:state] - description = obj_attr[:description] - title = obj_attr[:title] - - merge_request_url = "#{project_url}/merge_requests/#{merge_request_id}" - merge_request_link = "merge request ##{merge_request_id}" - message = "#{user_name} #{state} #{merge_request_link} in " \ - "#{project_link}: #{title}" - - if description - description = format_body(description) - message << description - end - - message - end - - def format_title(title) - "" + title.lines.first.chomp + "" - end - - def create_note_message(data) - data = HashWithIndifferentAccess.new(data) - user_name = data[:user][:name] - - repo_attr = HashWithIndifferentAccess.new(data[:repository]) - - obj_attr = HashWithIndifferentAccess.new(data[:object_attributes]) - note = obj_attr[:note] - note_url = obj_attr[:url] - noteable_type = obj_attr[:noteable_type] - - case noteable_type - when "Commit" - commit_attr = HashWithIndifferentAccess.new(data[:commit]) - subject_desc = commit_attr[:id] - subject_desc = Commit.truncate_sha(subject_desc) - subject_type = "commit" - title = format_title(commit_attr[:message]) - when "Issue" - subj_attr = HashWithIndifferentAccess.new(data[:issue]) - subject_id = subj_attr[:iid] - subject_desc = "##{subject_id}" - subject_type = "issue" - title = format_title(subj_attr[:title]) - when "MergeRequest" - subj_attr = HashWithIndifferentAccess.new(data[:merge_request]) - subject_id = subj_attr[:iid] - subject_desc = "##{subject_id}" - subject_type = "merge request" - title = format_title(subj_attr[:title]) - when "Snippet" - subj_attr = HashWithIndifferentAccess.new(data[:snippet]) - subject_id = subj_attr[:id] - subject_desc = "##{subject_id}" - subject_type = "snippet" - title = format_title(subj_attr[:title]) - end - - subject_html = "#{subject_type} #{subject_desc}" - message = "#{user_name} commented on #{subject_html} in #{project_link}: " - message << title - - if note - note = format_body(note) - message << note - end - - message - end - - def project_name - project.name_with_namespace.gsub(/\s/, '') - end - - def project_url - project.web_url - end - - def project_link - "#{project_name}" - end - - def is_update?(data) - data[:object_attributes][:action] == 'update' - end -end diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb deleted file mode 100644 index e9e1e276e7d690aaf3c0dcc71bbc8c83e10eeadb..0000000000000000000000000000000000000000 --- a/app/models/project_services/irker_service.rb +++ /dev/null @@ -1,163 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'uri' - -class IrkerService < Service - prop_accessor :colorize_messages, :recipients, :channels - validates :recipients, presence: true, if: :activated? - validate :check_recipients_count, if: :activated? - - before_validation :get_channels - after_initialize :initialize_settings - - # Writer for RSpec tests - attr_writer :settings - - def initialize_settings - # See the documentation (doc/project_services/irker.md) for possible values - # here - @settings ||= { - server_ip: 'localhost', - server_port: 6659, - max_channels: 3, - default_irc_uri: nil - } - end - - def title - 'Irker (IRC gateway)' - end - - def description - 'Send IRC messages, on update, to a list of recipients through an Irker '\ - 'gateway.' - end - - def help - msg = 'Recipients have to be specified with a full URI: '\ - 'irc[s]://irc.network.net[:port]/#channel. Special cases: if you want '\ - 'the channel to be a nickname instead, append ",isnick" to the channel '\ - 'name; if the channel is protected by a secret password, append '\ - '"?key=secretpassword" to the URI.' - - unless @settings[:default_irc].nil? - msg += ' Note that a default IRC URI is provided by this service\'s '\ - "administrator: #{default_irc}. You can thus just give a channel name." - end - msg - end - - def to_param - 'irker' - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - IrkerWorker.perform_async(project_id, channels, - colorize_messages, data, @settings) - end - - def fields - [ - { type: 'textarea', name: 'recipients', - placeholder: 'Recipients/channels separated by whitespaces' }, - { type: 'checkbox', name: 'colorize_messages' }, - ] - end - - private - - def check_recipients_count - return true if recipients.nil? || recipients.empty? - - if recipients.split(/\s+/).count > max_chans - errors.add(:recipients, "are limited to #{max_chans}") - end - end - - def max_chans - @settings[:max_channels] - end - - def get_channels - return true unless :activated? - return true if recipients.nil? || recipients.empty? - - map_recipients - - errors.add(:recipients, 'are all invalid') if channels.empty? - true - end - - def map_recipients - self.channels = recipients.split(/\s+/).map do |recipient| - format_channel default_irc_uri, recipient - end - channels.reject! &:nil? - end - - def default_irc_uri - default_irc = @settings[:default_irc_uri] - if !(default_irc.nil? || default_irc[-1] == '/') - default_irc += '/' - end - default_irc - end - - def format_channel(default_irc, recipient) - cnt = 0 - url = nil - - # Try to parse the chan as a full URI - begin - uri = URI.parse(recipient) - raise URI::InvalidURIError if uri.scheme.nil? && cnt == 0 - rescue URI::InvalidURIError - unless default_irc.nil? - cnt += 1 - recipient = "#{default_irc}#{recipient}" - retry if cnt == 1 - end - else - url = consider_uri uri - end - url - end - - def consider_uri(uri) - # Authorize both irc://domain.com/#chan and irc://domain.com/chan - if uri.is_a?(URI) && uri.scheme[/^ircs?\z/] && !uri.path.nil? - # Do not authorize irc://domain.com/ - if uri.fragment.nil? && uri.path.length > 1 - uri.to_s - else - # Authorize irc://domain.com/smthg#chan - # The irker daemon will deal with it by concatenating smthg and - # chan, thus sending messages on #smthgchan - uri.to_s - end - end - end -end diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb deleted file mode 100644 index c8ab9d63b7499ce78a97ecdb7d39e28623a32ad6..0000000000000000000000000000000000000000 --- a/app/models/project_services/issue_tracker_service.rb +++ /dev/null @@ -1,125 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class IssueTrackerService < Service - - validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated? - - def category - :issue_tracker - end - - def default? - false - end - - def issue_url(iid) - self.issues_url.gsub(':id', iid.to_s) - end - - def project_path - project_url - end - - def new_issue_path - new_issue_url - end - - def issue_path(iid) - issue_url(iid) - end - - def fields - [ - { type: 'text', name: 'description', placeholder: description }, - { type: 'text', name: 'project_url', placeholder: 'Project url' }, - { type: 'text', name: 'issues_url', placeholder: 'Issue url' }, - { type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' } - ] - end - - def initialize_properties - if properties.nil? - if enabled_in_gitlab_config - self.properties = { - title: issues_tracker['title'], - project_url: add_issues_tracker_id(issues_tracker['project_url']), - issues_url: add_issues_tracker_id(issues_tracker['issues_url']), - new_issue_url: add_issues_tracker_id(issues_tracker['new_issue_url']) - } - else - self.properties = {} - end - end - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - message = "#{self.type} was unable to reach #{self.project_url}. Check the url and try again." - result = false - - begin - url = URI.parse(self.project_url) - - if url.host && url.port - http = Net::HTTP.start(url.host, url.port, { open_timeout: 5, read_timeout: 5 }) - response = http.head("/") - - if response - message = "#{self.type} received response #{response.code} when attempting to connect to #{self.project_url}" - result = true - end - end - rescue Timeout::Error, SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED => error - message = "#{self.type} had an error when trying to connect to #{self.project_url}: #{error.message}" - end - Rails.logger.info(message) - result - end - - private - - def enabled_in_gitlab_config - Gitlab.config.issues_tracker && - Gitlab.config.issues_tracker.values.any? && - issues_tracker - end - - def issues_tracker - Gitlab.config.issues_tracker[to_param] - end - - def add_issues_tracker_id(url) - if self.project - id = self.project.issues_tracker_id - - if id - url = url.gsub(":issues_tracker_id", id) - end - end - - url - end -end diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb deleted file mode 100644 index fcd9dc2f33674ccd1fbd781434c542e1dc3cc298..0000000000000000000000000000000000000000 --- a/app/models/project_services/jira_service.rb +++ /dev/null @@ -1,58 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class JiraService < IssueTrackerService - include Rails.application.routes.url_helpers - - prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url - - def help - issue_tracker_link = help_page_path("integration", "external-issue-tracker") - - line1 = "Setting `project_url`, `issues_url` and `new_issue_url` will "\ - "allow a user to easily navigate to the Jira issue tracker. "\ - "See the [integration doc](#{issue_tracker_link}) for details." - - line2 = 'Support for referencing commits and automatic closing of Jira issues directly ' \ - 'from GitLab is [available in GitLab EE.](http://doc.gitlab.com/ee/integration/jira.html)' - - [line1, line2].join("\n\n") - end - - def title - if self.properties && self.properties['title'].present? - self.properties['title'] - else - 'JIRA' - end - end - - def description - if self.properties && self.properties['description'].present? - self.properties['description'] - else - 'Jira issue tracker' - end - end - - def to_param - 'jira' - end -end diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb deleted file mode 100644 index ade9ee97873999daa81fba4880cd736b9d6319aa..0000000000000000000000000000000000000000 --- a/app/models/project_services/pivotaltracker_service.rb +++ /dev/null @@ -1,72 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class PivotaltrackerService < Service - include HTTParty - - prop_accessor :token - validates :token, presence: true, if: :activated? - - def title - 'PivotalTracker' - end - - def description - 'Project Management Software (Source Commits Endpoint)' - end - - def to_param - 'pivotaltracker' - end - - def fields - [ - { type: 'text', name: 'token', placeholder: '' } - ] - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - url = 'https://www.pivotaltracker.com/services/v5/source_commits' - data[:commits].each do |commit| - message = { - 'source_commit' => { - 'commit_id' => commit[:id], - 'author' => commit[:author][:name], - 'url' => commit[:url], - 'message' => commit[:message] - } - } - PivotaltrackerService.post( - url, - body: message.to_json, - headers: { - 'Content-Type' => 'application/json', - 'X-TrackerToken' => token - } - ) - end - end -end diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb deleted file mode 100644 index 53edf522e9a729a5827911c85c04a8b049ad3d29..0000000000000000000000000000000000000000 --- a/app/models/project_services/pushover_service.rb +++ /dev/null @@ -1,125 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class PushoverService < Service - include HTTParty - base_uri 'https://api.pushover.net/1' - - prop_accessor :api_key, :user_key, :device, :priority, :sound - validates :api_key, :user_key, :priority, presence: true, if: :activated? - - def title - 'Pushover' - end - - def description - 'Pushover makes it easy to get real-time notifications on your Android device, iPhone, iPad, and Desktop.' - end - - def to_param - 'pushover' - end - - def fields - [ - { type: 'text', name: 'api_key', placeholder: 'Your application key' }, - { type: 'text', name: 'user_key', placeholder: 'Your user key' }, - { type: 'text', name: 'device', placeholder: 'Leave blank for all active devices' }, - { type: 'select', name: 'priority', choices: - [ - ['Lowest Priority', -2], - ['Low Priority', -1], - ['Normal Priority', 0], - ['High Priority', 1] - ], - default_choice: 0 - }, - { type: 'select', name: 'sound', choices: - [ - ['Device default sound', nil], - ['Pushover (default)', 'pushover'], - ['Bike', 'bike'], - ['Bugle', 'bugle'], - ['Cash Register', 'cashregister'], - ['Classical', 'classical'], - ['Cosmic', 'cosmic'], - ['Falling', 'falling'], - ['Gamelan', 'gamelan'], - ['Incoming', 'incoming'], - ['Intermission', 'intermission'], - ['Magic', 'magic'], - ['Mechanical', 'mechanical'], - ['Piano Bar', 'pianobar'], - ['Siren', 'siren'], - ['Space Alarm', 'spacealarm'], - ['Tug Boat', 'tugboat'], - ['Alien Alarm (long)', 'alien'], - ['Climb (long)', 'climb'], - ['Persistent (long)', 'persistent'], - ['Pushover Echo (long)', 'echo'], - ['Up Down (long)', 'updown'], - ['None (silent)', 'none'] - ] - }, - ] - end - - def supported_events - %w(push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - ref = Gitlab::Git.ref_name(data[:ref]) - before = data[:before] - after = data[:after] - - if Gitlab::Git.blank_ref?(before) - message = "#{data[:user_name]} pushed new branch \"#{ref}\"." - elsif Gitlab::Git.blank_ref?(after) - message = "#{data[:user_name]} deleted branch \"#{ref}\"." - else - message = "#{data[:user_name]} push to branch \"#{ref}\"." - end - - if data[:total_commits_count] > 0 - message << "\nTotal commits count: #{data[:total_commits_count]}" - end - - pushover_data = { - token: api_key, - user: user_key, - device: device, - priority: priority, - title: "#{project.name_with_namespace}", - message: message, - url: data[:repository][:homepage], - url_title: "See project #{project.name_with_namespace}" - } - - # Sound parameter MUST NOT be sent to API if not selected - if sound - pushover_data.merge!(sound: sound) - end - - PushoverService.post('/messages.json', body: pushover_data) - end -end diff --git a/app/models/project_services/redmine_service.rb b/app/models/project_services/redmine_service.rb deleted file mode 100644 index dd9ba97ee1fac487d66f5315955002abef9da6d9..0000000000000000000000000000000000000000 --- a/app/models/project_services/redmine_service.rb +++ /dev/null @@ -1,44 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class RedmineService < IssueTrackerService - - prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url - - def title - if self.properties && self.properties['title'].present? - self.properties['title'] - else - 'Redmine' - end - end - - def description - if self.properties && self.properties['description'].present? - self.properties['description'] - else - 'Redmine issue tracker' - end - end - - def to_param - 'redmine' - end -end diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb deleted file mode 100644 index 36d9874edd32d3b8d8a3f22c377458817858b935..0000000000000000000000000000000000000000 --- a/app/models/project_services/slack_service.rb +++ /dev/null @@ -1,105 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class SlackService < Service - prop_accessor :webhook, :username, :channel - validates :webhook, presence: true, if: :activated? - - def title - 'Slack' - end - - def description - 'A team communication tool for the 21st century' - end - - def to_param - 'slack' - end - - def fields - [ - { type: 'text', name: 'webhook', - placeholder: 'https://hooks.slack.com/services/...' }, - { type: 'text', name: 'username', placeholder: 'username' }, - { type: 'text', name: 'channel', placeholder: '#channel' } - ] - end - - def supported_events - %w(push issue merge_request note tag_push) - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - return unless webhook.present? - - object_kind = data[:object_kind] - - data = data.merge( - project_url: project_url, - project_name: project_name - ) - - # WebHook events often have an 'update' event that follows a 'open' or - # 'close' action. Ignore update events for now to prevent duplicate - # messages from arriving. - - message = \ - case object_kind - when "push", "tag_push" - PushMessage.new(data) - when "issue" - IssueMessage.new(data) unless is_update?(data) - when "merge_request" - MergeMessage.new(data) unless is_update?(data) - when "note" - NoteMessage.new(data) - end - - opt = {} - opt[:channel] = channel if channel - opt[:username] = username if username - - if message - notifier = Slack::Notifier.new(webhook, opt) - notifier.ping(message.pretext, attachments: message.attachments) - end - end - - private - - def project_name - project.name_with_namespace.gsub(/\s/, '') - end - - def project_url - project.web_url - end - - def is_update?(data) - data[:object_attributes][:action] == 'update' - end -end - -require "slack_service/issue_message" -require "slack_service/push_message" -require "slack_service/merge_message" -require "slack_service/note_message" diff --git a/app/models/project_services/slack_service/base_message.rb b/app/models/project_services/slack_service/base_message.rb deleted file mode 100644 index aa00d6061a118473758411a0b7581836ff9db291..0000000000000000000000000000000000000000 --- a/app/models/project_services/slack_service/base_message.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'slack-notifier' - -class SlackService - class BaseMessage - def initialize(params) - raise NotImplementedError - end - - def pretext - format(message) - end - - def attachments - raise NotImplementedError - end - - private - - def message - raise NotImplementedError - end - - def format(string) - Slack::Notifier::LinkFormatter.format(string) - end - - def attachment_color - '#345' - end - end -end diff --git a/app/models/project_services/slack_service/issue_message.rb b/app/models/project_services/slack_service/issue_message.rb deleted file mode 100644 index 5af24a80609352547ab9b5b29549f6cd463a3a07..0000000000000000000000000000000000000000 --- a/app/models/project_services/slack_service/issue_message.rb +++ /dev/null @@ -1,56 +0,0 @@ -class SlackService - class IssueMessage < BaseMessage - attr_reader :user_name - attr_reader :title - attr_reader :project_name - attr_reader :project_url - attr_reader :issue_iid - attr_reader :issue_url - attr_reader :action - attr_reader :state - attr_reader :description - - def initialize(params) - @user_name = params[:user][:name] - @project_name = params[:project_name] - @project_url = params[:project_url] - - obj_attr = params[:object_attributes] - obj_attr = HashWithIndifferentAccess.new(obj_attr) - @title = obj_attr[:title] - @issue_iid = obj_attr[:iid] - @issue_url = obj_attr[:url] - @action = obj_attr[:action] - @state = obj_attr[:state] - @description = obj_attr[:description] - end - - def attachments - return [] unless opened_issue? - - description_message - end - - private - - def message - "#{user_name} #{state} #{issue_link} in #{project_link}: *#{title}*" - end - - def opened_issue? - action == "open" - end - - def description_message - [{ text: format(description), color: attachment_color }] - end - - def project_link - "[#{project_name}](#{project_url})" - end - - def issue_link - "[issue ##{issue_iid}](#{issue_url})" - end - end -end diff --git a/app/models/project_services/slack_service/merge_message.rb b/app/models/project_services/slack_service/merge_message.rb deleted file mode 100644 index e792c258f7394a5e6e1c12dd222c75cd93d39620..0000000000000000000000000000000000000000 --- a/app/models/project_services/slack_service/merge_message.rb +++ /dev/null @@ -1,60 +0,0 @@ -class SlackService - class MergeMessage < BaseMessage - attr_reader :user_name - attr_reader :project_name - attr_reader :project_url - attr_reader :merge_request_id - attr_reader :source_branch - attr_reader :target_branch - attr_reader :state - attr_reader :title - - def initialize(params) - @user_name = params[:user][:name] - @project_name = params[:project_name] - @project_url = params[:project_url] - - obj_attr = params[:object_attributes] - obj_attr = HashWithIndifferentAccess.new(obj_attr) - @merge_request_id = obj_attr[:iid] - @source_branch = obj_attr[:source_branch] - @target_branch = obj_attr[:target_branch] - @state = obj_attr[:state] - @title = format_title(obj_attr[:title]) - end - - def pretext - format(message) - end - - def attachments - [] - end - - private - - def format_title(title) - '*' + title.lines.first.chomp + '*' - end - - def message - merge_request_message - end - - def project_link - "[#{project_name}](#{project_url})" - end - - def merge_request_message - "#{user_name} #{state} #{merge_request_link} in #{project_link}: #{title}" - end - - def merge_request_link - "[merge request ##{merge_request_id}](#{merge_request_url})" - end - - def merge_request_url - "#{project_url}/merge_requests/#{merge_request_id}" - end - end -end diff --git a/app/models/project_services/slack_service/note_message.rb b/app/models/project_services/slack_service/note_message.rb deleted file mode 100644 index 074478b292da5ef73cd6cd7860bf0893404d1cfa..0000000000000000000000000000000000000000 --- a/app/models/project_services/slack_service/note_message.rb +++ /dev/null @@ -1,82 +0,0 @@ -class SlackService - class NoteMessage < BaseMessage - attr_reader :message - attr_reader :user_name - attr_reader :project_name - attr_reader :project_link - attr_reader :note - attr_reader :note_url - attr_reader :title - - def initialize(params) - params = HashWithIndifferentAccess.new(params) - @user_name = params[:user][:name] - @project_name = params[:project_name] - @project_url = params[:project_url] - - obj_attr = params[:object_attributes] - obj_attr = HashWithIndifferentAccess.new(obj_attr) - @note = obj_attr[:note] - @note_url = obj_attr[:url] - noteable_type = obj_attr[:noteable_type] - - case noteable_type - when "Commit" - create_commit_note(HashWithIndifferentAccess.new(params[:commit])) - when "Issue" - create_issue_note(HashWithIndifferentAccess.new(params[:issue])) - when "MergeRequest" - create_merge_note(HashWithIndifferentAccess.new(params[:merge_request])) - when "Snippet" - create_snippet_note(HashWithIndifferentAccess.new(params[:snippet])) - end - end - - def attachments - description_message - end - - private - - def format_title(title) - title.lines.first.chomp - end - - def create_commit_note(commit) - commit_sha = commit[:id] - commit_sha = Commit.truncate_sha(commit_sha) - commit_link = "[commit #{commit_sha}](#{@note_url})" - title = format_title(commit[:message]) - @message = "#{@user_name} commented on #{commit_link} in #{project_link}: *#{title}*" - end - - def create_issue_note(issue) - issue_iid = issue[:iid] - note_link = "[issue ##{issue_iid}](#{@note_url})" - title = format_title(issue[:title]) - @message = "#{@user_name} commented on #{note_link} in #{project_link}: *#{title}*" - end - - def create_merge_note(merge_request) - merge_request_id = merge_request[:iid] - merge_request_link = "[merge request ##{merge_request_id}](#{@note_url})" - title = format_title(merge_request[:title]) - @message = "#{@user_name} commented on #{merge_request_link} in #{project_link}: *#{title}*" - end - - def create_snippet_note(snippet) - snippet_id = snippet[:id] - snippet_link = "[snippet ##{snippet_id}](#{@note_url})" - title = format_title(snippet[:title]) - @message = "#{@user_name} commented on #{snippet_link} in #{project_link}: *#{title}*" - end - - def description_message - [{ text: format(@note), color: attachment_color }] - end - - def project_link - "[#{@project_name}](#{@project_url})" - end - end -end diff --git a/app/models/project_services/slack_service/push_message.rb b/app/models/project_services/slack_service/push_message.rb deleted file mode 100644 index b26f3e9ddce9f392d6cc06e9446fb03a49fa1de3..0000000000000000000000000000000000000000 --- a/app/models/project_services/slack_service/push_message.rb +++ /dev/null @@ -1,110 +0,0 @@ -class SlackService - class PushMessage < BaseMessage - attr_reader :after - attr_reader :before - attr_reader :commits - attr_reader :project_name - attr_reader :project_url - attr_reader :ref - attr_reader :ref_type - attr_reader :user_name - - def initialize(params) - @after = params[:after] - @before = params[:before] - @commits = params.fetch(:commits, []) - @project_name = params[:project_name] - @project_url = params[:project_url] - @ref_type = Gitlab::Git.tag_ref?(params[:ref]) ? 'tag' : 'branch' - @ref = Gitlab::Git.ref_name(params[:ref]) - @user_name = params[:user_name] - end - - def pretext - format(message) - end - - def attachments - return [] if new_branch? || removed_branch? - - commit_message_attachments - end - - private - - def message - if new_branch? - new_branch_message - elsif removed_branch? - removed_branch_message - else - push_message - end - end - - def format(string) - Slack::Notifier::LinkFormatter.format(string) - end - - def new_branch_message - "#{user_name} pushed new #{ref_type} #{branch_link} to #{project_link}" - end - - def removed_branch_message - "#{user_name} removed #{ref_type} #{ref} from #{project_link}" - end - - def push_message - "#{user_name} pushed to #{ref_type} #{branch_link} of #{project_link} (#{compare_link})" - end - - def commit_messages - commits.map { |commit| compose_commit_message(commit) }.join("\n") - end - - def commit_message_attachments - [{ text: format(commit_messages), color: attachment_color }] - end - - def compose_commit_message(commit) - author = commit[:author][:name] - id = Commit.truncate_sha(commit[:id]) - message = commit[:message] - url = commit[:url] - - "[#{id}](#{url}): #{message} - #{author}" - end - - def new_branch? - Gitlab::Git.blank_ref?(before) - end - - def removed_branch? - Gitlab::Git.blank_ref?(after) - end - - def branch_url - "#{project_url}/commits/#{ref}" - end - - def compare_url - "#{project_url}/compare/#{before}...#{after}" - end - - def branch_link - "[#{ref}](#{branch_url})" - end - - def project_link - "[#{project_name}](#{project_url})" - end - - def compare_link - "[Compare changes](#{compare_url})" - end - - def attachment_color - '#345' - end - end -end diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb deleted file mode 100644 index 3c002a1634b8c9535e577f829145e27f1c224c9b..0000000000000000000000000000000000000000 --- a/app/models/project_services/teamcity_service.rb +++ /dev/null @@ -1,145 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# note_events :boolean default(TRUE), not null -# - -class TeamcityService < CiService - include HTTParty - - prop_accessor :teamcity_url, :build_type, :username, :password - - validates :teamcity_url, - presence: true, - format: { with: /\A#{URI.regexp}\z/ }, if: :activated? - validates :build_type, presence: true, if: :activated? - validates :username, - presence: true, - if: ->(service) { service.password? }, if: :activated? - validates :password, - presence: true, - if: ->(service) { service.username? }, if: :activated? - - attr_accessor :response - - after_save :compose_service_hook, if: :activated? - - def compose_service_hook - hook = service_hook || build_service_hook - hook.save - end - - def title - 'JetBrains TeamCity CI' - end - - def description - 'A continuous integration and build server' - end - - def help - 'The build configuration in Teamcity must use the build format '\ - 'number %build.vcs.number% '\ - 'you will also want to configure monitoring of all branches so merge '\ - 'requests build, that setting is in the vsc root advanced settings.' - end - - def to_param - 'teamcity' - end - - def supported_events - %w(push) - end - - def fields - [ - { type: 'text', name: 'teamcity_url', - placeholder: 'TeamCity root URL like https://teamcity.example.com' }, - { type: 'text', name: 'build_type', - placeholder: 'Build configuration ID' }, - { type: 'text', name: 'username', - placeholder: 'A user with permissions to trigger a manual build' }, - { type: 'password', name: 'password' }, - ] - end - - def build_info(sha) - url = URI.parse("#{teamcity_url}/httpAuth/app/rest/builds/"\ - "branch:unspecified:any,number:#{sha}") - auth = { - username: username, - password: password, - } - @response = HTTParty.get("#{url}", verify: false, basic_auth: auth) - end - - def build_page(sha, ref) - build_info(sha) if @response.nil? || !@response.code - - if @response.code != 200 - # If actual build link can't be determined, - # send user to build summary page. - "#{teamcity_url}/viewLog.html?buildTypeId=#{build_type}" - else - # If actual build link is available, go to build result page. - built_id = @response['build']['id'] - "#{teamcity_url}/viewLog.html?buildId=#{built_id}"\ - "&buildTypeId=#{build_type}" - end - end - - def commit_status(sha, ref) - build_info(sha) if @response.nil? || !@response.code - return :error unless @response.code == 200 || @response.code == 404 - - status = if @response.code == 404 - 'Pending' - else - @response['build']['status'] - end - - if status.include?('SUCCESS') - 'success' - elsif status.include?('FAILURE') - 'failed' - elsif status.include?('Pending') - 'pending' - else - :error - end - end - - def execute(data) - return unless supported_events.include?(data[:object_kind]) - - auth = { - username: username, - password: password, - } - - branch = Gitlab::Git.ref_name(data[:ref]) - - self.class.post("#{teamcity_url}/httpAuth/app/rest/buildQueue", - body: ""\ - ""\ - '', - headers: { 'Content-type' => 'application/xml' }, - basic_auth: auth - ) - end -end diff --git a/app/models/project_snippet.rb b/app/models/project_snippet.rb deleted file mode 100644 index 9e2c1b0e18e8413b344ff08ed7c52330ee2a5951..0000000000000000000000000000000000000000 --- a/app/models/project_snippet.rb +++ /dev/null @@ -1,28 +0,0 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string(255) -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string(255) -# expires_at :datetime -# type :string(255) -# visibility_level :integer default(0), not null -# - -class ProjectSnippet < Snippet - belongs_to :project - belongs_to :author, class_name: "User" - - validates :project, presence: true - - # Scopes - scope :fresh, -> { order("created_at DESC") } - scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) } - scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) } -end diff --git a/app/models/project_team.rb b/app/models/project_team.rb deleted file mode 100644 index 56e49af23246f79775ae3983c7c806797bd3741e..0000000000000000000000000000000000000000 --- a/app/models/project_team.rb +++ /dev/null @@ -1,169 +0,0 @@ -class ProjectTeam - attr_accessor :project - - def initialize(project) - @project = project - end - - # Shortcut to add users - # - # Use: - # @team << [@user, :master] - # @team << [@users, :master] - # - def <<(args) - users, access, current_user = *args - - if users.respond_to?(:each) - add_users(users, access, current_user) - else - add_user(users, access, current_user) - end - end - - def find(user_id) - user = project.users.find_by(id: user_id) - - if group - user ||= group.users.find_by(id: user_id) - end - - user - end - - def find_member(user_id) - member = project.project_members.find_by(user_id: user_id) - - # If user is not in project members - # we should check for group membership - if group && !member - member = group.group_members.find_by(user_id: user_id) - end - - member - end - - def add_users(users, access, current_user = nil) - ProjectMember.add_users_into_projects( - [project.id], - users, - access, - current_user - ) - end - - def add_user(user, access, current_user = nil) - add_users([user], access, current_user) - end - - # Remove all users from project team - def truncate - ProjectMember.truncate_team(project) - end - - def users - members - end - - def members - @members ||= fetch_members - end - - def guests - @guests ||= fetch_members(:guests) - end - - def reporters - @reporters ||= fetch_members(:reporters) - end - - def developers - @developers ||= fetch_members(:developers) - end - - def masters - @masters ||= fetch_members(:masters) - end - - def import(source_project, current_user = nil) - target_project = project - - source_members = source_project.project_members.to_a - target_user_ids = target_project.project_members.pluck(:user_id) - - source_members.reject! do |member| - # Skip if user already present in team - !member.invite? && target_user_ids.include?(member.user_id) - end - - source_members.map! do |member| - new_member = member.dup - new_member.id = nil - new_member.source = target_project - new_member.created_by = current_user - new_member - end - - ProjectMember.transaction do - source_members.each do |member| - member.save - end - end - - true - rescue - false - end - - def guest?(user) - max_member_access(user.id) == Gitlab::Access::GUEST - end - - def reporter?(user) - max_member_access(user.id) == Gitlab::Access::REPORTER - end - - def developer?(user) - max_member_access(user.id) == Gitlab::Access::DEVELOPER - end - - def master?(user) - max_member_access(user.id) == Gitlab::Access::MASTER - end - - def member?(user_id) - !!find_member(user_id) - end - - def max_member_access(user_id) - access = [] - access << project.project_members.find_by(user_id: user_id).try(:access_field) - - if group - access << group.group_members.find_by(user_id: user_id).try(:access_field) - end - - access.compact.max - end - - private - - def fetch_members(level = nil) - project_members = project.project_members - group_members = group ? group.group_members : [] - - if level - project_members = project_members.send(level) - group_members = group_members.send(level) if group - end - - user_ids = project_members.pluck(:user_id) - user_ids.push(*group_members.pluck(:user_id)) if group - - User.where(id: user_ids) - end - - def group - project.group - end -end diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb deleted file mode 100644 index 772c868d9cd0088307f7bab85d8166878a528a1c..0000000000000000000000000000000000000000 --- a/app/models/project_wiki.rb +++ /dev/null @@ -1,149 +0,0 @@ -class ProjectWiki - include Gitlab::ShellAdapter - - MARKUPS = { - 'Markdown' => :markdown, - 'RDoc' => :rdoc, - 'AsciiDoc' => :asciidoc - } unless defined?(MARKUPS) - - class CouldNotCreateWikiError < StandardError; end - - # Returns a string describing what went wrong after - # an operation fails. - attr_reader :error_message - - def initialize(project, user = nil) - @project = project - @user = user - end - - def path - @project.path + '.wiki' - end - - def path_with_namespace - @project.path_with_namespace + ".wiki" - end - - def url_to_repo - gitlab_shell.url_to_repo(path_with_namespace) - end - - def ssh_url_to_repo - url_to_repo - end - - def http_url_to_repo - [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('') - end - - # Returns the Gollum::Wiki object. - def wiki - @wiki ||= begin - Gollum::Wiki.new(path_to_repo) - rescue Gollum::NoSuchPathError - create_repo! - end - end - - def empty? - pages.empty? - end - - # Returns an Array of Gitlab WikiPage instances or an - # empty Array if this Wiki has no pages. - def pages - wiki.pages.map { |page| WikiPage.new(self, page, true) } - end - - # Finds a page within the repository based on a tile - # or slug. - # - # title - The human readable or parameterized title of - # the page. - # - # Returns an initialized WikiPage instance or nil - def find_page(title, version = nil) - page_title, page_dir = page_title_and_dir(title) - if page = wiki.page(page_title, version, page_dir) - WikiPage.new(self, page, true) - else - nil - end - end - - def find_file(name, version = nil, try_on_disk = true) - version = wiki.ref if version.nil? # Gollum::Wiki#file ? - if wiki_file = wiki.file(name, version, try_on_disk) - wiki_file - else - nil - end - end - - def create_page(title, content, format = :markdown, message = nil) - commit = commit_details(:created, message, title) - - wiki.write_page(title, format, content, commit) - rescue Gollum::DuplicatePageError => e - @error_message = "Duplicate page: #{e.message}" - return false - end - - def update_page(page, content, format = :markdown, message = nil) - commit = commit_details(:updated, message, page.title) - - wiki.update_page(page, page.name, format, content, commit) - end - - def delete_page(page, message = nil) - wiki.delete_page(page, commit_details(:deleted, message, page.title)) - end - - def page_title_and_dir(title) - title_array = title.split("/") - title = title_array.pop - [title, title_array.join("/")] - end - - def search_files(query) - repository.search_files(query, default_branch) - end - - def repository - Repository.new(path_with_namespace, default_branch) - end - - def default_branch - wiki.class.default_ref - end - - private - - def create_repo! - if init_repo(path_with_namespace) - Gollum::Wiki.new(path_to_repo) - else - raise CouldNotCreateWikiError - end - end - - def init_repo(path_with_namespace) - gitlab_shell.add_repository(path_with_namespace) - end - - def commit_details(action, message = nil, title = nil) - commit_message = message || default_message(action, title) - - { email: @user.email, name: @user.name, message: commit_message } - end - - def default_message(action, title) - "#{@user.username} #{action} page: #{title}" - end - - def path_to_repo - @path_to_repo ||= File.join(Gitlab.config.gitlab_shell.repos_path, "#{path_with_namespace}.git") - end -end diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb deleted file mode 100644 index 97207ba12726c4cd6179f6e623d5a447ff0de39f..0000000000000000000000000000000000000000 --- a/app/models/protected_branch.rb +++ /dev/null @@ -1,23 +0,0 @@ -# == Schema Information -# -# Table name: protected_branches -# -# id :integer not null, primary key -# project_id :integer not null -# name :string(255) not null -# created_at :datetime -# updated_at :datetime -# developers_can_push :boolean default(FALSE), not null -# - -class ProtectedBranch < ActiveRecord::Base - include Gitlab::ShellAdapter - - belongs_to :project - validates :name, presence: true - validates :project, presence: true - - def commit - project.repository.commit(self.name) - end -end diff --git a/app/models/repository.rb b/app/models/repository.rb deleted file mode 100644 index 263a436d5210469c5566684a5fbb2b7a52129f7c..0000000000000000000000000000000000000000 --- a/app/models/repository.rb +++ /dev/null @@ -1,377 +0,0 @@ -class Repository - include Gitlab::ShellAdapter - - attr_accessor :raw_repository, :path_with_namespace - - def initialize(path_with_namespace, default_branch = nil) - @path_with_namespace = path_with_namespace - @raw_repository = Gitlab::Git::Repository.new(path_to_repo) if path_with_namespace - rescue Gitlab::Git::Repository::NoRepository - nil - end - - # Return absolute path to repository - def path_to_repo - @path_to_repo ||= File.expand_path( - File.join(Gitlab.config.gitlab_shell.repos_path, path_with_namespace + ".git") - ) - end - - def exists? - raw_repository - end - - def empty? - raw_repository.empty? - end - - def commit(id = 'HEAD') - return nil unless raw_repository - commit = Gitlab::Git::Commit.find(raw_repository, id) - commit = Commit.new(commit) if commit - commit - rescue Rugged::OdbError - nil - end - - def commits(ref, path = nil, limit = nil, offset = nil, skip_merges = false) - commits = Gitlab::Git::Commit.where( - repo: raw_repository, - ref: ref, - path: path, - limit: limit, - offset: offset, - ) - commits = Commit.decorate(commits) if commits.present? - commits - end - - def commits_between(from, to) - commits = Gitlab::Git::Commit.between(raw_repository, from, to) - commits = Commit.decorate(commits) if commits.present? - commits - end - - def find_branch(name) - branches.find { |branch| branch.name == name } - end - - def find_tag(name) - tags.find { |tag| tag.name == name } - end - - def add_branch(branch_name, ref) - cache.expire(:branch_names) - @branches = nil - - gitlab_shell.add_branch(path_with_namespace, branch_name, ref) - end - - def add_tag(tag_name, ref, message = nil) - cache.expire(:tag_names) - @tags = nil - - gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message) - end - - def rm_branch(branch_name) - cache.expire(:branch_names) - @branches = nil - - gitlab_shell.rm_branch(path_with_namespace, branch_name) - end - - def rm_tag(tag_name) - cache.expire(:tag_names) - @tags = nil - - gitlab_shell.rm_tag(path_with_namespace, tag_name) - end - - def round_commit_count - if commit_count > 10000 - '10000+' - elsif commit_count > 5000 - '5000+' - elsif commit_count > 1000 - '1000+' - else - commit_count - end - end - - def branch_names - cache.fetch(:branch_names) { raw_repository.branch_names } - end - - def tag_names - cache.fetch(:tag_names) { raw_repository.tag_names } - end - - def commit_count - cache.fetch(:commit_count) do - begin - raw_repository.commit_count(self.root_ref) - rescue - 0 - end - end - end - - # Return repo size in megabytes - # Cached in redis - def size - cache.fetch(:size) { raw_repository.size } - end - - def expire_cache - %i(size branch_names tag_names commit_count graph_log - readme version contribution_guide changelog license).each do |key| - cache.expire(key) - end - end - - def graph_log - cache.fetch(:graph_log) do - commits = raw_repository.log(limit: 6000, skip_merges: true, - ref: root_ref) - - commits.map do |rugged_commit| - commit = Gitlab::Git::Commit.new(rugged_commit) - - { - author_name: commit.author_name, - author_email: commit.author_email, - additions: commit.stats.additions, - deletions: commit.stats.deletions, - } - end - end - end - - def lookup_cache - @lookup_cache ||= {} - end - - def method_missing(m, *args, &block) - if m == :lookup && !block_given? - lookup_cache[m] ||= {} - lookup_cache[m][args.join(":")] ||= raw_repository.send(m, *args, &block) - else - raw_repository.send(m, *args, &block) - end - end - - def respond_to?(method) - return true if raw_repository.respond_to?(method) - - super - end - - def blob_at(sha, path) - Gitlab::Git::Blob.find(self, sha, path) - end - - def blob_by_oid(oid) - Gitlab::Git::Blob.raw(self, oid) - end - - def readme - cache.fetch(:readme) { tree(:head).readme } - end - - def version - cache.fetch(:version) do - tree(:head).blobs.find do |file| - file.name.downcase == 'version' - end - end - end - - def contribution_guide - cache.fetch(:contribution_guide) do - tree(:head).blobs.find do |file| - file.contributing? - end - end - end - - def changelog - cache.fetch(:changelog) do - tree(:head).blobs.find do |file| - file.name =~ /\A(changelog|history)/i - end - end - end - - def license - cache.fetch(:license) do - tree(:head).blobs.find do |file| - file.name =~ /\Alicense/i - end - end - end - - def head_commit - @head_commit ||= commit(self.root_ref) - end - - def head_tree - @head_tree ||= Tree.new(self, head_commit.sha, nil) - end - - def tree(sha = :head, path = nil) - if sha == :head - if path.nil? - return head_tree - else - sha = head_commit.sha - end - end - - Tree.new(self, sha, path) - end - - def blob_at_branch(branch_name, path) - last_commit = commit(branch_name) - - if last_commit - blob_at(last_commit.sha, path) - else - nil - end - end - - # Returns url for submodule - # - # Ex. - # @repository.submodule_url_for('master', 'rack') - # # => git@localhost:rack.git - # - def submodule_url_for(ref, path) - if submodules(ref).any? - submodule = submodules(ref)[path] - - if submodule - submodule['url'] - end - end - end - - def last_commit_for_path(sha, path) - args = %W(git rev-list --max-count=1 #{sha} -- #{path}) - sha = Gitlab::Popen.popen(args, path_to_repo).first.strip - commit(sha) - end - - # Remove archives older than 2 hours - def clean_old_archives - repository_downloads_path = Gitlab.config.gitlab.repository_downloads_path - - return unless File.directory?(repository_downloads_path) - - Gitlab::Popen.popen(%W(find #{repository_downloads_path} -not -path #{repository_downloads_path} -mmin +120 -delete)) - end - - def branches_sorted_by(value) - case value - when 'recently_updated' - branches.sort do |a, b| - commit(b.target).committed_date <=> commit(a.target).committed_date - end - when 'last_updated' - branches.sort do |a, b| - commit(a.target).committed_date <=> commit(b.target).committed_date - end - else - branches - end - end - - def contributors - commits = self.commits(nil, nil, 2000, 0, true) - - commits.group_by(&:author_email).map do |email, commits| - contributor = Gitlab::Contributor.new - contributor.email = email - - commits.each do |commit| - if contributor.name.blank? - contributor.name = commit.author_name - end - - contributor.commits += 1 - end - - contributor - end - end - - def blob_for_diff(commit, diff) - file = blob_at(commit.id, diff.new_path) - - unless file - file = prev_blob_for_diff(commit, diff) - end - - file - end - - def prev_blob_for_diff(commit, diff) - if commit.parent_id - blob_at(commit.parent_id, diff.old_path) - end - end - - def branch_names_contains(sha) - args = %W(git branch --contains #{sha}) - names = Gitlab::Popen.popen(args, path_to_repo).first - - if names.respond_to?(:split) - names = names.split("\n").map(&:strip) - - names.each do |name| - name.slice! '* ' - end - - names - else - [] - end - end - - def tag_names_contains(sha) - args = %W(git tag --contains #{sha}) - names = Gitlab::Popen.popen(args, path_to_repo).first - - if names.respond_to?(:split) - names = names.split("\n").map(&:strip) - - names.each do |name| - name.slice! '* ' - end - - names - else - [] - end - end - - def branches - @branches ||= raw_repository.branches - end - - def tags - @tags ||= raw_repository.tags - end - - def root_ref - @root_ref ||= raw_repository.root_ref - end - - private - - def cache - @cache ||= RepositoryCache.new(path_with_namespace) - end -end diff --git a/app/models/service.rb b/app/models/service.rb deleted file mode 100644 index 393cf55a69f296f5e17c0bbbd1c7f877a9a6a19b..0000000000000000000000000000000000000000 --- a/app/models/service.rb +++ /dev/null @@ -1,153 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -# To add new service you should build a class inherited from Service -# and implement a set of methods -class Service < ActiveRecord::Base - include Sortable - serialize :properties, JSON - - default_value_for :active, false - default_value_for :push_events, true - default_value_for :issues_events, true - default_value_for :merge_requests_events, true - default_value_for :tag_push_events, true - default_value_for :note_events, true - - after_initialize :initialize_properties - - belongs_to :project - has_one :service_hook - - validates :project_id, presence: true, unless: Proc.new { |service| service.template? } - - scope :visible, -> { where.not(type: 'GitlabIssueTrackerService') } - - scope :push_hooks, -> { where(push_events: true, active: true) } - scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) } - scope :issue_hooks, -> { where(issues_events: true, active: true) } - scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) } - scope :note_hooks, -> { where(note_events: true, active: true) } - - def activated? - active - end - - def template? - template - end - - def category - :common - end - - def initialize_properties - self.properties = {} if properties.nil? - end - - def title - # implement inside child - end - - def description - # implement inside child - end - - def help - # implement inside child - end - - def to_param - # implement inside child - end - - def fields - # implement inside child - [] - end - - def supported_events - %w(push tag_push issue merge_request) - end - - def execute - # implement inside child - end - - def can_test? - !project.empty_repo? - end - - # Provide convenient accessor methods - # for each serialized property. - def self.prop_accessor(*args) - args.each do |arg| - class_eval %{ - def #{arg} - properties['#{arg}'] - end - - def #{arg}=(value) - self.properties['#{arg}'] = value - end - } - end - end - - def async_execute(data) - return unless supported_events.include?(data[:object_kind]) - - Sidekiq::Client.enqueue(ProjectServiceWorker, id, data) - end - - def issue_tracker? - self.category == :issue_tracker - end - - def self.available_services_names - %w( - asana - assembla - bamboo - buildkite - campfire - custom_issue_tracker - emails_on_push - external_wiki - flowdock - gemnasium - gitlab_ci - hipchat - irker - jira - pivotaltracker - pushover - redmine - slack - teamcity - ) - end - - def self.create_from_template(project_id, template) - service = template.dup - service.template = false - service.project_id = project_id - service if service.save - end -end diff --git a/app/models/snippet.rb b/app/models/snippet.rb deleted file mode 100644 index b35e72c4bdb00f5c05293bd191acb57547bbdf87..0000000000000000000000000000000000000000 --- a/app/models/snippet.rb +++ /dev/null @@ -1,103 +0,0 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string(255) -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string(255) -# expires_at :datetime -# type :string(255) -# visibility_level :integer default(0), not null -# - -class Snippet < ActiveRecord::Base - include Sortable - include Linguist::BlobHelper - include Gitlab::VisibilityLevel - - default_value_for :visibility_level, Snippet::PRIVATE - - belongs_to :author, class_name: "User" - - has_many :notes, as: :noteable, dependent: :destroy - - delegate :name, :email, to: :author, prefix: true, allow_nil: true - - validates :author, presence: true - validates :title, presence: true, length: { within: 0..255 } - validates :file_name, - presence: true, - length: { within: 0..255 }, - format: { with: Gitlab::Regex.file_name_regex, - message: Gitlab::Regex.file_name_regex_message } - validates :content, presence: true - validates :visibility_level, inclusion: { in: Gitlab::VisibilityLevel.values } - - # Scopes - scope :are_internal, -> { where(visibility_level: Snippet::INTERNAL) } - scope :are_private, -> { where(visibility_level: Snippet::PRIVATE) } - scope :are_public, -> { where(visibility_level: Snippet::PUBLIC) } - scope :public_and_internal, -> { where(visibility_level: [Snippet::PUBLIC, Snippet::INTERNAL]) } - scope :fresh, -> { order("created_at DESC") } - scope :expired, -> { where(["expires_at IS NOT NULL AND expires_at < ?", Time.current]) } - scope :non_expired, -> { where(["expires_at IS NULL OR expires_at > ?", Time.current]) } - - def self.content_types - [ - ".rb", ".py", ".pl", ".scala", ".c", ".cpp", ".java", - ".haml", ".html", ".sass", ".scss", ".xml", ".php", ".erb", - ".js", ".sh", ".coffee", ".yml", ".md" - ] - end - - def data - content - end - - def hook_attrs - attributes - end - - def size - 0 - end - - def name - file_name - end - - def sanitized_file_name - file_name.gsub(/[^a-zA-Z0-9_\-\.]+/, '') - end - - def mode - nil - end - - def expired? - expires_at && expires_at < Time.current - end - - def visibility_level_field - visibility_level - end - - class << self - def search(query) - where('(title LIKE :query OR file_name LIKE :query)', query: "%#{query}%") - end - - def search_code(query) - where('(content LIKE :query)', query: "%#{query}%") - end - - def accessible_to(user) - where('visibility_level IN (?) OR author_id = ?', [Snippet::INTERNAL, Snippet::PUBLIC], user) - end - end -end diff --git a/app/models/subscription.rb b/app/models/subscription.rb deleted file mode 100644 index dd75d3ab8ba39d8fa66c1e2d22f5c61dc39194e8..0000000000000000000000000000000000000000 --- a/app/models/subscription.rb +++ /dev/null @@ -1,21 +0,0 @@ -# == Schema Information -# -# Table name: subscriptions -# -# id :integer not null, primary key -# user_id :integer -# subscribable_id :integer -# subscribable_type :string(255) -# subscribed :boolean -# created_at :datetime -# updated_at :datetime -# - -class Subscription < ActiveRecord::Base - belongs_to :user - belongs_to :subscribable, polymorphic: true - - validates :user_id, - uniqueness: { scope: [:subscribable_id, :subscribable_type] }, - presence: true -end diff --git a/app/models/tree.rb b/app/models/tree.rb deleted file mode 100644 index f279e896cda38bb176eaad6d62599352d87114f4..0000000000000000000000000000000000000000 --- a/app/models/tree.rb +++ /dev/null @@ -1,53 +0,0 @@ -class Tree - include Gitlab::MarkdownHelper - - attr_accessor :repository, :sha, :path, :entries - - def initialize(repository, sha, path = '/') - path = '/' if path.blank? - - @repository = repository - @sha = sha - @path = path - - git_repo = @repository.raw_repository - @entries = Gitlab::Git::Tree.where(git_repo, @sha, @path) - end - - def readme - return @readme if defined?(@readme) - - available_readmes = blobs.select(&:readme?) - - if available_readmes.count == 0 - return @readme = nil - end - - # Take the first previewable readme, or the first available readme, if we - # can't preview any of them - readme_tree = available_readmes.find do |readme| - previewable?(readme.name) - end || available_readmes.first - - readme_path = path == '/' ? readme_tree.name : File.join(path, readme_tree.name) - - git_repo = repository.raw_repository - @readme = Gitlab::Git::Blob.find(git_repo, sha, readme_path) - end - - def trees - @entries.select(&:dir?) - end - - def blobs - @entries.select(&:file?) - end - - def submodules - @entries.select(&:submodule?) - end - - def sorted_entries - trees + blobs + submodules - end -end diff --git a/app/models/user.rb b/app/models/user.rb deleted file mode 100644 index d6b93afe73906825af8568f486450fdc994ef504..0000000000000000000000000000000000000000 --- a/app/models/user.rb +++ /dev/null @@ -1,614 +0,0 @@ -# == Schema Information -# -# Table name: users -# -# id :integer not null, primary key -# email :string(255) default(""), not null -# encrypted_password :string(255) default(""), not null -# reset_password_token :string(255) -# reset_password_sent_at :datetime -# remember_created_at :datetime -# sign_in_count :integer default(0) -# current_sign_in_at :datetime -# last_sign_in_at :datetime -# current_sign_in_ip :string(255) -# last_sign_in_ip :string(255) -# created_at :datetime -# updated_at :datetime -# name :string(255) -# admin :boolean default(FALSE), not null -# projects_limit :integer default(10) -# skype :string(255) default(""), not null -# linkedin :string(255) default(""), not null -# twitter :string(255) default(""), not null -# authentication_token :string(255) -# theme_id :integer default(1), not null -# bio :string(255) -# failed_attempts :integer default(0) -# locked_at :datetime -# username :string(255) -# can_create_group :boolean default(TRUE), not null -# can_create_team :boolean default(TRUE), not null -# state :string(255) -# color_scheme_id :integer default(1), not null -# notification_level :integer default(1), not null -# password_expires_at :datetime -# created_by_id :integer -# last_credential_check_at :datetime -# avatar :string(255) -# confirmation_token :string(255) -# confirmed_at :datetime -# confirmation_sent_at :datetime -# unconfirmed_email :string(255) -# hide_no_ssh_key :boolean default(FALSE) -# website_url :string(255) default(""), not null -# github_access_token :string(255) -# gitlab_access_token :string(255) -# notification_email :string(255) -# hide_no_password :boolean default(FALSE) -# password_automatically_set :boolean default(FALSE) -# bitbucket_access_token :string(255) -# bitbucket_access_token_secret :string(255) -# public_email :string(255) default(""), not null -# - -require 'carrierwave/orm/activerecord' -require 'file_size_validator' - -class User < ActiveRecord::Base - include Sortable - include Gitlab::ConfigHelper - include TokenAuthenticatable - extend Gitlab::ConfigHelper - include Gitlab::CurrentSettings - - default_value_for :admin, false - default_value_for :can_create_group, gitlab_config.default_can_create_group - default_value_for :can_create_team, false - default_value_for :hide_no_ssh_key, false - default_value_for :hide_no_password, false - default_value_for :theme_id, gitlab_config.default_theme - - devise :database_authenticatable, :lockable, :async, - :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable - - attr_accessor :force_random_password - - # Virtual attribute for authenticating by either username or email - attr_accessor :login - - # - # Relations - # - - # Namespace for personal projects - has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id, class_name: "Namespace" - - # Profile - has_many :keys, dependent: :destroy - has_many :emails, dependent: :destroy - has_many :identities, dependent: :destroy - - # Groups - has_many :members, dependent: :destroy - has_many :project_members, source: 'ProjectMember' - has_many :group_members, source: 'GroupMember' - has_many :groups, through: :group_members - has_many :owned_groups, -> { where members: { access_level: Gitlab::Access::OWNER } }, through: :group_members, source: :group - has_many :masters_groups, -> { where members: { access_level: Gitlab::Access::MASTER } }, through: :group_members, source: :group - - # Projects - has_many :groups_projects, through: :groups, source: :projects - has_many :personal_projects, through: :namespace, source: :projects - has_many :projects, through: :project_members - has_many :created_projects, foreign_key: :creator_id, class_name: 'Project' - has_many :users_star_projects, dependent: :destroy - has_many :starred_projects, through: :users_star_projects, source: :project - - has_many :snippets, dependent: :destroy, foreign_key: :author_id, class_name: "Snippet" - has_many :project_members, dependent: :destroy, class_name: 'ProjectMember' - has_many :issues, dependent: :destroy, foreign_key: :author_id - has_many :notes, dependent: :destroy, foreign_key: :author_id - has_many :merge_requests, dependent: :destroy, foreign_key: :author_id - has_many :events, dependent: :destroy, foreign_key: :author_id, class_name: "Event" - has_many :subscriptions, dependent: :destroy - has_many :recent_events, -> { order "id DESC" }, foreign_key: :author_id, class_name: "Event" - has_many :assigned_issues, dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue" - has_many :assigned_merge_requests, dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest" - has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy - - - # - # Validations - # - validates :name, presence: true - validates :email, presence: true, email: { strict_mode: true }, uniqueness: true - validates :notification_email, presence: true, email: { strict_mode: true } - validates :public_email, presence: true, email: { strict_mode: true }, allow_blank: true, uniqueness: true - validates :bio, length: { maximum: 255 }, allow_blank: true - validates :projects_limit, presence: true, numericality: { greater_than_or_equal_to: 0 } - validates :username, - presence: true, - uniqueness: { case_sensitive: false }, - exclusion: { in: Gitlab::Blacklist.path }, - format: { with: Gitlab::Regex.namespace_regex, - message: Gitlab::Regex.namespace_regex_message } - - validates :notification_level, inclusion: { in: Notification.notification_levels }, presence: true - validate :namespace_uniq, if: ->(user) { user.username_changed? } - validate :avatar_type, if: ->(user) { user.avatar_changed? } - validate :unique_email, if: ->(user) { user.email_changed? } - validate :owns_notification_email, if: ->(user) { user.notification_email_changed? } - validates :avatar, file_size: { maximum: 200.kilobytes.to_i } - - before_validation :generate_password, on: :create - before_validation :sanitize_attrs - before_validation :set_notification_email, if: ->(user) { user.email_changed? } - before_validation :set_public_email, if: ->(user) { user.public_email_changed? } - - before_save :ensure_authentication_token - after_save :ensure_namespace_correct - after_initialize :set_projects_limit - after_create :post_create_hook - after_destroy :post_destroy_hook - - - alias_attribute :private_token, :authentication_token - - delegate :path, to: :namespace, allow_nil: true, prefix: true - - state_machine :state, initial: :active do - event :block do - transition active: :blocked - end - - event :activate do - transition blocked: :active - end - end - - mount_uploader :avatar, AvatarUploader - - # Scopes - scope :admins, -> { where(admin: true) } - scope :blocked, -> { with_state(:blocked) } - scope :active, -> { with_state(:active) } - scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all } - scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') } - - # - # Class methods - # - class << self - # Devise method overridden to allow sign in with email or username - def find_for_database_authentication(warden_conditions) - conditions = warden_conditions.dup - if login = conditions.delete(:login) - where(conditions).where(["lower(username) = :value OR lower(email) = :value", { value: login.downcase }]).first - else - where(conditions).first - end - end - - def sort(method) - case method.to_s - when 'recent_sign_in' then reorder(last_sign_in_at: :desc) - when 'oldest_sign_in' then reorder(last_sign_in_at: :asc) - else - order_by(method) - end - end - - def find_for_commit(email, name) - # Prefer email match over name match - User.where(email: email).first || - User.joins(:emails).where(emails: { email: email }).first || - User.where(name: name).first - end - - def filter(filter_name) - case filter_name - when "admins"; self.admins - when "blocked"; self.blocked - when "wop"; self.without_projects - else - self.active - end - end - - def search(query) - where("lower(name) LIKE :query OR lower(email) LIKE :query OR lower(username) LIKE :query", query: "%#{query.downcase}%") - end - - def by_login(login) - where('lower(username) = :value OR lower(email) = :value', - value: login.to_s.downcase).first - end - - def by_username_or_id(name_or_id) - where('users.username = ? OR users.id = ?', name_or_id.to_s, name_or_id.to_i).first - end - - def build_user(attrs = {}) - User.new(attrs) - end - end - - # - # Instance methods - # - - def to_param - username - end - - def notification - @notification ||= Notification.new(self) - end - - def generate_password - if self.force_random_password - self.password = self.password_confirmation = Devise.friendly_token.first(8) - end - end - - def generate_reset_token - @reset_token, enc = Devise.token_generator.generate(self.class, :reset_password_token) - - self.reset_password_token = enc - self.reset_password_sent_at = Time.now.utc - - @reset_token - end - - def namespace_uniq - namespace_name = self.username - existing_namespace = Namespace.by_path(namespace_name) - if existing_namespace && existing_namespace != self.namespace - self.errors.add :username, "already exists" - end - end - - def avatar_type - unless self.avatar.image? - self.errors.add :avatar, "only images allowed" - end - end - - def unique_email - self.errors.add(:email, 'has already been taken') if Email.exists?(email: self.email) - end - - def owns_notification_email - self.errors.add(:notification_email, "is not an email you own") unless self.all_emails.include?(self.notification_email) - end - - # Groups user has access to - def authorized_groups - @authorized_groups ||= begin - group_ids = (groups.pluck(:id) + authorized_projects.pluck(:namespace_id)) - Group.where(id: group_ids) - end - end - - - # Projects user has access to - def authorized_projects - @authorized_projects ||= begin - project_ids = personal_projects.pluck(:id) - project_ids.push(*groups_projects.pluck(:id)) - project_ids.push(*projects.pluck(:id).uniq) - Project.where(id: project_ids) - end - end - - def owned_projects - @owned_projects ||= begin - Project.where(namespace_id: owned_groups.pluck(:id).push(namespace.id)).joins(:namespace) - end - end - - # Team membership in authorized projects - def tm_in_authorized_projects - ProjectMember.where(source_id: authorized_projects.map(&:id), user_id: self.id) - end - - def is_admin? - admin - end - - def require_ssh_key? - keys.count == 0 - end - - def require_password? - password_automatically_set? && !ldap_user? - end - - def can_change_username? - gitlab_config.username_changing_enabled - end - - def can_create_project? - projects_limit_left > 0 - end - - def can_create_group? - can?(:create_group, nil) - end - - def abilities - Ability.abilities - end - - def can_select_namespace? - several_namespaces? || admin - end - - def can?(action, subject) - abilities.allowed?(self, action, subject) - end - - def first_name - name.split.first unless name.blank? - end - - def cared_merge_requests - MergeRequest.cared(self) - end - - def projects_limit_left - projects_limit - personal_projects.count - end - - def projects_limit_percent - return 100 if projects_limit.zero? - (personal_projects.count.to_f / projects_limit) * 100 - end - - def recent_push(project_id = nil) - # Get push events not earlier than 2 hours ago - events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours) - events = events.where(project_id: project_id) if project_id - - # Take only latest one - events = events.recent.limit(1).first - end - - def projects_sorted_by_activity - authorized_projects.sorted_by_activity - end - - def several_namespaces? - owned_groups.any? || masters_groups.any? - end - - def namespace_id - namespace.try :id - end - - def name_with_username - "#{name} (#{username})" - end - - def tm_of(project) - project.project_member_by_id(self.id) - end - - def already_forked?(project) - !!fork_of(project) - end - - def fork_of(project) - links = ForkedProjectLink.where(forked_from_project_id: project, forked_to_project_id: personal_projects) - - if links.any? - links.first.forked_to_project - else - nil - end - end - - def ldap_user? - identities.exists?(["provider LIKE ? AND extern_uid IS NOT NULL", "ldap%"]) - end - - def ldap_identity - @ldap_identity ||= identities.find_by(["provider LIKE ?", "ldap%"]) - end - - def project_deploy_keys - DeployKey.in_projects(self.authorized_projects.pluck(:id)) - end - - def accessible_deploy_keys - @accessible_deploy_keys ||= begin - key_ids = project_deploy_keys.pluck(:id) - key_ids.push(*DeployKey.are_public.pluck(:id)) - DeployKey.where(id: key_ids) - end - end - - def created_by - User.find_by(id: created_by_id) if created_by_id - end - - def sanitize_attrs - %w(name username skype linkedin twitter bio).each do |attr| - value = self.send(attr) - self.send("#{attr}=", Sanitize.clean(value)) if value.present? - end - end - - def set_notification_email - if self.notification_email.blank? || !self.all_emails.include?(self.notification_email) - self.notification_email = self.email - end - end - - def set_public_email - if self.public_email.blank? || !self.all_emails.include?(self.public_email) - self.public_email = '' - end - end - - def set_projects_limit - connection_default_value_defined = new_record? && !projects_limit_changed? - return unless self.projects_limit.nil? || connection_default_value_defined - - self.projects_limit = current_application_settings.default_projects_limit - end - - def requires_ldap_check? - if !Gitlab.config.ldap.enabled - false - elsif ldap_user? - !last_credential_check_at || (last_credential_check_at + 1.hour) < Time.now - else - false - end - end - - def solo_owned_groups - @solo_owned_groups ||= owned_groups.select do |group| - group.owners == [self] - end - end - - def with_defaults - User.defaults.each do |k, v| - self.send("#{k}=", v) - end - - self - end - - def can_leave_project?(project) - project.namespace != namespace && - project.project_member(self) - end - - # Reset project events cache related to this user - # - # Since we do cache @event we need to reset cache in special cases: - # * when the user changes their avatar - # Events cache stored like events/23-20130109142513. - # The cache key includes updated_at timestamp. - # Thus it will automatically generate a new fragment - # when the event is updated because the key changes. - def reset_events_cache - Event.where(author_id: self.id). - order('id DESC').limit(1000). - update_all(updated_at: Time.now) - end - - def full_website_url - return "http://#{website_url}" if website_url !~ /\Ahttps?:\/\// - - website_url - end - - def short_website_url - website_url.sub(/\Ahttps?:\/\//, '') - end - - def all_ssh_keys - keys.map(&:key) - end - - def temp_oauth_email? - email.start_with?('temp-email-for-oauth') - end - - def public_profile? - authorized_projects.public_only.any? - end - - def avatar_url(size = nil) - if avatar.present? - [gitlab_config.url, avatar.url].join - else - GravatarService.new.execute(email, size) - end - end - - def all_emails - [self.email, *self.emails.map(&:email)] - end - - def hook_attrs - { - name: name, - username: username, - avatar_url: avatar_url - } - end - - def ensure_namespace_correct - # Ensure user has namespace - self.create_namespace!(path: self.username, name: self.username) unless self.namespace - - if self.username_changed? - self.namespace.update_attributes(path: self.username, name: self.username) - end - end - - def post_create_hook - log_info("User \"#{self.name}\" (#{self.email}) was created") - notification_service.new_user(self, @reset_token) if self.created_by_id - system_hook_service.execute_hooks_for(self, :create) - end - - def post_destroy_hook - log_info("User \"#{self.name}\" (#{self.email}) was removed") - system_hook_service.execute_hooks_for(self, :destroy) - end - - def notification_service - NotificationService.new - end - - def log_info(message) - Gitlab::AppLogger.info message - end - - def system_hook_service - SystemHooksService.new - end - - def starred?(project) - starred_projects.exists?(project) - end - - def toggle_star(project) - user_star_project = users_star_projects. - where(project: project, user: self).take - if user_star_project - user_star_project.destroy - else - UsersStarProject.create!(project: project, user: self) - end - end - - def manageable_namespaces - @manageable_namespaces ||= - begin - namespaces = [] - namespaces << namespace - namespaces += owned_groups - namespaces += masters_groups - end - end - - def oauth_authorized_tokens - Doorkeeper::AccessToken.where(resource_owner_id: self.id, revoked_at: nil) - end - - def contributed_projects_ids - Event.contributions.where(author_id: self). - where("created_at > ?", Time.now - 1.year). - reorder(project_id: :desc). - select(:project_id). - uniq.map(&:project_id) - end -end diff --git a/app/models/users_star_project.rb b/app/models/users_star_project.rb deleted file mode 100644 index 3d49cb059496e872ec63f7c312919d8e4d8659e4..0000000000000000000000000000000000000000 --- a/app/models/users_star_project.rb +++ /dev/null @@ -1,19 +0,0 @@ -# == Schema Information -# -# Table name: users_star_projects -# -# id :integer not null, primary key -# project_id :integer not null -# user_id :integer not null -# created_at :datetime -# updated_at :datetime -# - -class UsersStarProject < ActiveRecord::Base - belongs_to :project, counter_cache: :star_count - belongs_to :user - - validates :user, presence: true - validates :user_id, uniqueness: { scope: [:project_id] } - validates :project, presence: true -end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb deleted file mode 100644 index e9413c34baed37f1e8008f5c7c8f14f8f8f1c5d7..0000000000000000000000000000000000000000 --- a/app/models/wiki_page.rb +++ /dev/null @@ -1,201 +0,0 @@ -class WikiPage - include ActiveModel::Validations - include ActiveModel::Conversion - include StaticModel - extend ActiveModel::Naming - - def self.primary_key - 'slug' - end - - def self.model_name - ActiveModel::Name.new(self, nil, 'wiki') - end - - def to_key - [:slug] - end - - validates :title, presence: true - validates :content, presence: true - - # The Gitlab ProjectWiki instance. - attr_reader :wiki - - # The raw Gollum::Page instance. - attr_reader :page - - # The attributes Hash used for storing and validating - # new Page values before writing to the Gollum repository. - attr_accessor :attributes - - def initialize(wiki, page = nil, persisted = false) - @wiki = wiki - @page = page - @persisted = persisted - @attributes = {}.with_indifferent_access - - set_attributes if persisted? - end - - # The escaped URL path of this page. - def slug - @attributes[:slug] - end - - alias_method :to_param, :slug - - # The formatted title of this page. - def title - if @attributes[:title] - @attributes[:title].gsub(/-+/, ' ') - else - "" - end - end - - # Sets the title of this page. - def title=(new_title) - @attributes[:title] = new_title - end - - # The raw content of this page. - def content - @attributes[:content] ||= if @page - @page.raw_data - end - end - - # The processed/formatted content of this page. - def formatted_content - @attributes[:formatted_content] ||= if @page - @page.formatted_data - end - end - - # The markup format for the page. - def format - @attributes[:format] || :markdown - end - - # The commit message for this page version. - def message - version.try(:message) - end - - # The Gitlab Commit instance for this page. - def version - return nil unless persisted? - - @version ||= @page.version - end - - # Returns an array of Gitlab Commit instances. - def versions - return [] unless persisted? - - @page.versions - end - - def commit - versions.first - end - - # Returns the Date that this latest version was - # created on. - def created_at - @page.version.date - end - - # Returns boolean True or False if this instance - # is an old version of the page. - def historical? - @page.historical? - end - - # Returns boolean True or False if this instance - # has been fully saved to disk or not. - def persisted? - @persisted == true - end - - # Creates a new Wiki Page. - # - # attr - Hash of attributes to set on the new page. - # :title - The title for the new page. - # :content - The raw markup content. - # :format - Optional symbol representing the - # content format. Can be any type - # listed in the ProjectWiki::MARKUPS - # Hash. - # :message - Optional commit message to set on - # the new page. - # - # Returns the String SHA1 of the newly created page - # or False if the save was unsuccessful. - def create(attr = {}) - @attributes.merge!(attr) - - save :create_page, title, content, format, message - end - - # Updates an existing Wiki Page, creating a new version. - # - # new_content - The raw markup content to replace the existing. - # format - Optional symbol representing the content format. - # See ProjectWiki::MARKUPS Hash for available formats. - # message - Optional commit message to set on the new version. - # - # Returns the String SHA1 of the newly created page - # or False if the save was unsuccessful. - def update(new_content = "", format = :markdown, message = nil) - @attributes[:content] = new_content - @attributes[:format] = format - - save :update_page, @page, content, format, message - end - - # Destroys the Wiki Page. - # - # Returns boolean True or False. - def delete - if wiki.delete_page(@page) - true - else - false - end - end - - private - - def set_attributes - attributes[:slug] = @page.escaped_url_path - attributes[:title] = @page.title - attributes[:format] = @page.format - end - - def save(method, *args) - project_wiki = wiki - if valid? && project_wiki.send(method, *args) - - page_details = if method == :update_page - # Use url_path instead of path to omit format extension - @page.url_path - else - title - end - - page_title, page_dir = project_wiki.page_title_and_dir(page_details) - gollum_wiki = project_wiki.wiki - @page = gollum_wiki.paged(page_title, page_dir) - - set_attributes - - @persisted = true - else - errors.add(:base, project_wiki.error_message) if project_wiki.error_message - @persisted = false - end - @persisted - end -end diff --git a/app/services/archive_repository_service.rb b/app/services/archive_repository_service.rb deleted file mode 100644 index e1b41527d8dc5d5efb86d47a1f11186de9845a6c..0000000000000000000000000000000000000000 --- a/app/services/archive_repository_service.rb +++ /dev/null @@ -1,62 +0,0 @@ -class ArchiveRepositoryService - attr_reader :project, :ref, :format - - def initialize(project, ref, format) - format ||= 'tar.gz' - @project, @ref, @format = project, ref, format.downcase - end - - def execute(options = {}) - project.repository.clean_old_archives - - raise "No archive file path" unless file_path - - return file_path if archived? - - unless archiving? - RepositoryArchiveWorker.perform_async(project.id, ref, format) - end - - archived = wait_until_archived(options[:timeout] || 5.0) - - file_path if archived - end - - private - - def storage_path - Gitlab.config.gitlab.repository_downloads_path - end - - def file_path - @file_path ||= project.repository.archive_file_path(ref, storage_path, format) - end - - def pid_file_path - @pid_file_path ||= project.repository.archive_pid_file_path(ref, storage_path, format) - end - - def archived? - File.exist?(file_path) - end - - def archiving? - File.exist?(pid_file_path) - end - - def wait_until_archived(timeout = 5.0) - return archived? if timeout == 0.0 - - t1 = Time.now - - begin - sleep 0.1 - - success = archived? - - t2 = Time.now - end until success || t2 - t1 >= timeout - - success - end -end diff --git a/app/services/base_service.rb b/app/services/base_service.rb deleted file mode 100644 index 6d9ed345914b356688422ad6dfbd72bf44d138b0..0000000000000000000000000000000000000000 --- a/app/services/base_service.rb +++ /dev/null @@ -1,66 +0,0 @@ -class BaseService - include Gitlab::CurrentSettings - - attr_accessor :project, :current_user, :params - - def initialize(project, user, params = {}) - @project, @current_user, @params = project, user, params.dup - end - - def abilities - Ability.abilities - end - - def can?(object, action, subject) - abilities.allowed?(object, action, subject) - end - - def notification_service - NotificationService.new - end - - def event_service - EventCreateService.new - end - - def log_info(message) - Gitlab::AppLogger.info message - end - - def system_hook_service - SystemHooksService.new - end - - # Add an error to the specified model for restricted visibility levels - def deny_visibility_level(model, denied_visibility_level = nil) - denied_visibility_level ||= model.visibility_level - - level_name = 'Unknown' - Gitlab::VisibilityLevel.options.each do |name, level| - level_name = name if level == denied_visibility_level - end - - model.errors.add( - :visibility_level, - "#{level_name} visibility has been restricted by your GitLab administrator" - ) - end - - private - - def error(message, http_status = nil) - result = { - message: message, - status: :error - } - - result[:http_status] = http_status if http_status - result - end - - def success - { - status: :success - } - end -end diff --git a/app/services/compare_service.rb b/app/services/compare_service.rb deleted file mode 100644 index 6aa9df4b19444aa24bff360649e71aafa9cc8986..0000000000000000000000000000000000000000 --- a/app/services/compare_service.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Compare 2 branches for one repo or between repositories -# and return Gitlab::CompareResult object that responds to commits and diffs -class CompareService - def execute(current_user, source_project, source_branch, target_project, target_branch) - # Try to compare branches to get commits list and diffs - # - # Note: Use satellite only when need to compare between two repos - # because satellites are slower than operations on bare repo - if target_project == source_project - Gitlab::CompareResult.new( - Gitlab::Git::Compare.new( - target_project.repository.raw_repository, - target_branch, - source_branch, - ) - ) - else - Gitlab::Satellite::CompareAction.new( - current_user, - target_project, - target_branch, - source_project, - source_branch - ).result - end - end -end diff --git a/app/services/create_branch_service.rb b/app/services/create_branch_service.rb deleted file mode 100644 index cf7ae4345f36b85fa8d21425e7b991ce4e5a8ca4..0000000000000000000000000000000000000000 --- a/app/services/create_branch_service.rb +++ /dev/null @@ -1,42 +0,0 @@ -require_relative 'base_service' - -class CreateBranchService < BaseService - def execute(branch_name, ref) - valid_branch = Gitlab::GitRefValidator.validate(branch_name) - if valid_branch == false - return error('Branch name invalid') - end - - repository = project.repository - existing_branch = repository.find_branch(branch_name) - if existing_branch - return error('Branch already exists') - end - - repository.add_branch(branch_name, ref) - new_branch = repository.find_branch(branch_name) - - if new_branch - push_data = build_push_data(project, current_user, new_branch) - - EventCreateService.new.push(project, current_user, push_data) - project.execute_hooks(push_data.dup, :push_hooks) - project.execute_services(push_data.dup, :push_hooks) - - success(new_branch) - else - error('Invalid reference name') - end - end - - def success(branch) - out = super() - out[:branch] = branch - out - end - - def build_push_data(project, user, branch) - Gitlab::PushDataBuilder. - build(project, user, Gitlab::Git::BLANK_SHA, branch.target, "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch.name}", []) - end -end diff --git a/app/services/create_snippet_service.rb b/app/services/create_snippet_service.rb deleted file mode 100644 index 101a3df5eee44f8cdaa6151f88f16bb28582d2b5..0000000000000000000000000000000000000000 --- a/app/services/create_snippet_service.rb +++ /dev/null @@ -1,20 +0,0 @@ -class CreateSnippetService < BaseService - def execute - if project.nil? - snippet = PersonalSnippet.new(params) - else - snippet = project.snippets.build(params) - end - - unless Gitlab::VisibilityLevel.allowed_for?(current_user, - params[:visibility_level]) - deny_visibility_level(snippet) - return snippet - end - - snippet.author = current_user - - snippet.save - snippet - end -end diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb deleted file mode 100644 index 25f9e2032464665f4137b817f6ac2c12dc3cab96..0000000000000000000000000000000000000000 --- a/app/services/create_tag_service.rb +++ /dev/null @@ -1,45 +0,0 @@ -require_relative 'base_service' - -class CreateTagService < BaseService - def execute(tag_name, ref, message) - valid_tag = Gitlab::GitRefValidator.validate(tag_name) - if valid_tag == false - return error('Tag name invalid') - end - - repository = project.repository - existing_tag = repository.find_tag(tag_name) - if existing_tag - return error('Tag already exists') - end - - message.strip! if message - - repository.add_tag(tag_name, ref, message) - new_tag = repository.find_tag(tag_name) - - if new_tag - push_data = create_push_data(project, current_user, new_tag) - - EventCreateService.new.push(project, current_user, push_data) - project.execute_hooks(push_data.dup, :tag_push_hooks) - project.execute_services(push_data.dup, :tag_push_hooks) - - success(new_tag) - else - error('Invalid reference name') - end - end - - def success(branch) - out = super() - out[:tag] = branch - out - end - - def create_push_data(project, user, tag) - commits = [project.repository.commit(tag.target)].compact - Gitlab::PushDataBuilder. - build(project, user, Gitlab::Git::BLANK_SHA, tag.target, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", commits, tag.message) - end -end diff --git a/app/services/delete_branch_service.rb b/app/services/delete_branch_service.rb deleted file mode 100644 index b19b112a0c4052560c450854dccaebc9e471c531..0000000000000000000000000000000000000000 --- a/app/services/delete_branch_service.rb +++ /dev/null @@ -1,56 +0,0 @@ -require_relative 'base_service' - -class DeleteBranchService < BaseService - def execute(branch_name) - repository = project.repository - branch = repository.find_branch(branch_name) - - # No such branch - unless branch - return error('No such branch', 404) - end - - if branch_name == repository.root_ref - return error('Cannot remove HEAD branch', 405) - end - - # Dont allow remove of protected branch - if project.protected_branch?(branch_name) - return error('Protected branch cant be removed', 405) - end - - # Dont allow user to remove branch if he is not allowed to push - unless current_user.can?(:push_code, project) - return error('You dont have push access to repo', 405) - end - - if repository.rm_branch(branch_name) - push_data = build_push_data(branch) - - EventCreateService.new.push(project, current_user, push_data) - project.execute_hooks(push_data.dup, :push_hooks) - project.execute_services(push_data.dup, :push_hooks) - - success('Branch was removed') - else - error('Failed to remove branch') - end - end - - def error(message, return_code = 400) - out = super(message) - out[:return_code] = return_code - out - end - - def success(message) - out = super() - out[:message] = message - out - end - - def build_push_data(branch) - Gitlab::PushDataBuilder - .build(project, current_user, branch.target, Gitlab::Git::BLANK_SHA, "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch.name}", []) - end -end diff --git a/app/services/delete_tag_service.rb b/app/services/delete_tag_service.rb deleted file mode 100644 index 0c8364011367b419d2762da155000afd86d8ec37..0000000000000000000000000000000000000000 --- a/app/services/delete_tag_service.rb +++ /dev/null @@ -1,42 +0,0 @@ -require_relative 'base_service' - -class DeleteTagService < BaseService - def execute(tag_name) - repository = project.repository - tag = repository.find_tag(tag_name) - - # No such tag - unless tag - return error('No such tag', 404) - end - - if repository.rm_tag(tag_name) - push_data = build_push_data(tag) - - EventCreateService.new.push(project, current_user, push_data) - project.execute_hooks(push_data.dup, :tag_push_hooks) - project.execute_services(push_data.dup, :tag_push_hooks) - - success('Tag was removed') - else - error('Failed to remove tag') - end - end - - def error(message, return_code = 400) - out = super(message) - out[:return_code] = return_code - out - end - - def success(message) - out = super() - out[:message] = message - out - end - - def build_push_data(tag) - Gitlab::PushDataBuilder - .build(project, current_user, tag.target, Gitlab::Git::BLANK_SHA, "#{Gitlab::Git::TAG_REF_PREFIX}#{tag.name}", []) - end -end diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb deleted file mode 100644 index 103d6b0a08bc4c3af8f385689399f39378715115..0000000000000000000000000000000000000000 --- a/app/services/event_create_service.rb +++ /dev/null @@ -1,84 +0,0 @@ -# EventCreateService class -# -# Used for creating events feed on dashboard after certain user action -# -# Ex. -# EventCreateService.new.new_issue(issue, current_user) -# -class EventCreateService - def open_issue(issue, current_user) - create_record_event(issue, current_user, Event::CREATED) - end - - def close_issue(issue, current_user) - create_record_event(issue, current_user, Event::CLOSED) - end - - def reopen_issue(issue, current_user) - create_record_event(issue, current_user, Event::REOPENED) - end - - def open_mr(merge_request, current_user) - create_record_event(merge_request, current_user, Event::CREATED) - end - - def close_mr(merge_request, current_user) - create_record_event(merge_request, current_user, Event::CLOSED) - end - - def reopen_mr(merge_request, current_user) - create_record_event(merge_request, current_user, Event::REOPENED) - end - - def merge_mr(merge_request, current_user) - create_record_event(merge_request, current_user, Event::MERGED) - end - - def open_milestone(milestone, current_user) - create_record_event(milestone, current_user, Event::CREATED) - end - - def close_milestone(milestone, current_user) - create_record_event(milestone, current_user, Event::CLOSED) - end - - def reopen_milestone(milestone, current_user) - create_record_event(milestone, current_user, Event::REOPENED) - end - - def leave_note(note, current_user) - create_record_event(note, current_user, Event::COMMENTED) - end - - def join_project(project, current_user) - create_event(project, current_user, Event::JOINED) - end - - def leave_project(project, current_user) - create_event(project, current_user, Event::LEFT) - end - - def create_project(project, current_user) - create_event(project, current_user, Event::CREATED) - end - - def push(project, current_user, push_data) - create_event(project, current_user, Event::PUSHED, data: push_data) - end - - private - - def create_record_event(record, current_user, status) - create_event(record.project, current_user, status, target_id: record.id, target_type: record.class.name) - end - - def create_event(project, current_user, status, attributes = {}) - attributes.reverse_merge!( - project: project, - action: status, - author_id: current_user.id - ) - - Event.create(attributes) - end -end diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb deleted file mode 100644 index bd245100955887034435ac0fe1c0a0584eaec9a9..0000000000000000000000000000000000000000 --- a/app/services/files/base_service.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Files - class BaseService < ::BaseService - attr_reader :ref, :path - - def initialize(project, user, params, ref, path = nil) - @project, @current_user, @params = project, user, params.dup - @ref = ref - @path = path - end - - private - - def repository - project.repository - end - end -end diff --git a/app/services/files/create_service.rb b/app/services/files/create_service.rb deleted file mode 100644 index 23833aa78ec81e14cea22f95933f5064f1aabd32..0000000000000000000000000000000000000000 --- a/app/services/files/create_service.rb +++ /dev/null @@ -1,52 +0,0 @@ -require_relative "base_service" - -module Files - class CreateService < BaseService - def execute - allowed = Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref) - - unless allowed - return error("You are not allowed to create file in this branch") - end - - file_name = File.basename(path) - file_path = path - - unless file_name =~ Gitlab::Regex.file_name_regex - return error( - 'Your changes could not be committed, because the file name ' + - Gitlab::Regex.file_name_regex_message - ) - end - - if project.empty_repo? - # everything is ok because repo does not have a commits yet - else - unless repository.branch_names.include?(ref) - return error("You can only create files if you are on top of a branch") - end - - blob = repository.blob_at_branch(ref, file_path) - - if blob - return error("Your changes could not be committed, because file with such name exists") - end - end - - - new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, file_path) - created_successfully = new_file_action.commit!( - params[:content], - params[:commit_message], - params[:encoding], - params[:new_branch] - ) - - if created_successfully - success - else - error("Your changes could not be committed, because the file has been changed") - end - end - end -end diff --git a/app/services/files/delete_service.rb b/app/services/files/delete_service.rb deleted file mode 100644 index 1497a0f883bcb32c5c85cdb3400a3960ea539de0..0000000000000000000000000000000000000000 --- a/app/services/files/delete_service.rb +++ /dev/null @@ -1,36 +0,0 @@ -require_relative "base_service" - -module Files - class DeleteService < BaseService - def execute - allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref) - - unless allowed - return error("You are not allowed to push into this branch") - end - - unless repository.branch_names.include?(ref) - return error("You can only create files if you are on top of a branch") - end - - blob = repository.blob_at_branch(ref, path) - - unless blob - return error("You can only edit text files") - end - - delete_file_action = Gitlab::Satellite::DeleteFileAction.new(current_user, project, ref, path) - - deleted_successfully = delete_file_action.commit!( - nil, - params[:commit_message] - ) - - if deleted_successfully - success - else - error("Your changes could not be committed, because the file has been changed") - end - end - end -end diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb deleted file mode 100644 index 0724d3ae6347b1150c0c40f81cb36fbdb7c9dea8..0000000000000000000000000000000000000000 --- a/app/services/files/update_service.rb +++ /dev/null @@ -1,39 +0,0 @@ -require_relative "base_service" - -module Files - class UpdateService < BaseService - def execute - allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref) - - unless allowed - return error("You are not allowed to push into this branch") - end - - unless repository.branch_names.include?(ref) - return error("You can only create files if you are on top of a branch") - end - - blob = repository.blob_at_branch(ref, path) - - unless blob - return error("You can only edit text files") - end - - edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path) - edit_file_action.commit!( - params[:content], - params[:commit_message], - params[:encoding], - params[:new_branch] - ) - - success - rescue Gitlab::Satellite::CheckoutFailed => ex - error("Your changes could not be committed because ref '#{ref}' could not be checked out", 400) - rescue Gitlab::Satellite::CommitFailed => ex - error("Your changes could not be committed. Maybe there was nothing to commit?", 409) - rescue Gitlab::Satellite::PushFailed => ex - error("Your changes could not be committed. Maybe the file was changed by another process?", 409) - end - end -end diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb deleted file mode 100644 index 31e0167d24757280188fc3ceed87cab890b733b6..0000000000000000000000000000000000000000 --- a/app/services/git_push_service.rb +++ /dev/null @@ -1,132 +0,0 @@ -class GitPushService - attr_accessor :project, :user, :push_data, :push_commits - include Gitlab::CurrentSettings - include Gitlab::Access - - # This method will be called after each git update - # and only if the provided user and project is present in GitLab. - # - # All callbacks for post receive action should be placed here. - # - # Next, this method: - # 1. Creates the push event - # 2. Ensures that the project satellite exists - # 3. Updates merge requests - # 4. Recognizes cross-references from commit messages - # 5. Executes the project's web hooks - # 6. Executes the project's services - # - def execute(project, user, oldrev, newrev, ref) - @project, @user = project, user - - project.ensure_satellite_exists - project.repository.expire_cache - project.update_repository_size - - if push_remove_branch?(ref, newrev) - @push_commits = [] - elsif push_to_new_branch?(ref, oldrev) - # Re-find the pushed commits. - if is_default_branch?(ref) - # Initial push to the default branch. Take the full history of that branch as "newly pushed". - @push_commits = project.repository.commits(newrev) - - # Set protection on the default branch if configured - if (current_application_settings.default_branch_protection != PROTECTION_NONE) - developers_can_push = current_application_settings.default_branch_protection == PROTECTION_DEV_CAN_PUSH ? true : false - project.protected_branches.create({ name: project.default_branch, developers_can_push: developers_can_push }) - end - else - # Use the pushed commits that aren't reachable by the default branch - # as a heuristic. This may include more commits than are actually pushed, but - # that shouldn't matter because we check for existing cross-references later. - @push_commits = project.repository.commits_between(project.default_branch, newrev) - - # don't process commits for the initial push to the default branch - process_commit_messages(ref) - end - elsif push_to_existing_branch?(ref, oldrev) - # Collect data for this git push - @push_commits = project.repository.commits_between(oldrev, newrev) - project.update_merge_requests(oldrev, newrev, ref, @user) - process_commit_messages(ref) - end - - @push_data = build_push_data(oldrev, newrev, ref) - - EventCreateService.new.push(project, user, @push_data) - project.execute_hooks(@push_data.dup, :push_hooks) - project.execute_services(@push_data.dup, :push_hooks) - end - - protected - - # Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched, - # close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables. - def process_commit_messages(ref) - is_default_branch = is_default_branch?(ref) - - @push_commits.each do |commit| - # Close issues if these commits were pushed to the project's default branch and the commit message matches the - # closing regex. Exclude any mentioned Issues from cross-referencing even if the commits are being pushed to - # a different branch. - issues_to_close = commit.closes_issues(project, user) - - # Load commit author only if needed. - # For push with 1k commits it prevents 900+ requests in database - author = nil - - if issues_to_close.present? && is_default_branch - author ||= commit_user(commit) - - issues_to_close.each do |issue| - Issues::CloseService.new(project, author, {}).execute(issue, commit) - end - end - - # Create cross-reference notes for any other references. Omit any issues that were referenced in an - # issue-closing phrase, or have already been mentioned from this commit (probably from this commit - # being pushed to a different branch). - refs = commit.references(project, user) - issues_to_close - refs.reject! { |r| commit.has_mentioned?(r) } - - if refs.present? - author ||= commit_user(commit) - - refs.each do |r| - Note.create_cross_reference_note(r, commit, author, project) - end - end - end - end - - def build_push_data(oldrev, newrev, ref) - Gitlab::PushDataBuilder. - build(project, user, oldrev, newrev, ref, push_commits) - end - - def push_to_existing_branch?(ref, oldrev) - # Return if this is not a push to a branch (e.g. new commits) - Gitlab::Git.branch_ref?(ref) && !Gitlab::Git.blank_ref?(oldrev) - end - - def push_to_new_branch?(ref, oldrev) - Gitlab::Git.branch_ref?(ref) && Gitlab::Git.blank_ref?(oldrev) - end - - def push_remove_branch?(ref, newrev) - Gitlab::Git.branch_ref?(ref) && Gitlab::Git.blank_ref?(newrev) - end - - def push_to_branch?(ref) - Gitlab::Git.branch_ref?(ref) - end - - def is_default_branch?(ref) - Gitlab::Git.branch_ref?(ref) && Gitlab::Git.ref_name(ref) == project.default_branch - end - - def commit_user(commit) - commit.author || user - end -end diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb deleted file mode 100644 index bf203bbd69272c1f80103403ae87b6a7937abb02..0000000000000000000000000000000000000000 --- a/app/services/git_tag_push_service.rb +++ /dev/null @@ -1,37 +0,0 @@ -class GitTagPushService - attr_accessor :project, :user, :push_data - - def execute(project, user, oldrev, newrev, ref) - @project, @user = project, user - - @push_data = build_push_data(oldrev, newrev, ref) - - EventCreateService.new.push(project, user, @push_data) - project.execute_hooks(@push_data.dup, :tag_push_hooks) - project.execute_services(@push_data.dup, :tag_push_hooks) - - project.repository.expire_cache - - true - end - - private - - def build_push_data(oldrev, newrev, ref) - commits = [] - message = nil - - if !Gitlab::Git.blank_ref?(newrev) - tag_name = Gitlab::Git.ref_name(ref) - tag = project.repository.find_tag(tag_name) - if tag && tag.target == newrev - commit = project.repository.commit(tag.target) - commits = [commit].compact - message = tag.message - end - end - - Gitlab::PushDataBuilder. - build(project, user, oldrev, newrev, ref, commits, message) - end -end diff --git a/app/services/gravatar_service.rb b/app/services/gravatar_service.rb deleted file mode 100644 index 4bee0c26a68e1e7c32c2ea91946ac8ee0c79e65a..0000000000000000000000000000000000000000 --- a/app/services/gravatar_service.rb +++ /dev/null @@ -1,30 +0,0 @@ -class GravatarService - include Gitlab::CurrentSettings - - def execute(email, size = nil) - if current_application_settings.gravatar_enabled? && email.present? - size = 40 if size.nil? || size <= 0 - - sprintf gravatar_url, - hash: Digest::MD5.hexdigest(email.strip.downcase), - size: size, - email: email.strip - end - end - - def gitlab_config - Gitlab.config.gitlab - end - - def gravatar_config - Gitlab.config.gravatar - end - - def gravatar_url - if gitlab_config.https - gravatar_config.ssl_url - else - gravatar_config.plain_url - end - end -end diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb deleted file mode 100644 index 5e1906ad2aec637beca13b6a00b794fd2d7c7eaf..0000000000000000000000000000000000000000 --- a/app/services/issuable_base_service.rb +++ /dev/null @@ -1,18 +0,0 @@ -class IssuableBaseService < BaseService - private - - def create_assignee_note(issuable) - Note.create_assignee_change_note( - issuable, issuable.project, current_user, issuable.assignee) - end - - def create_milestone_note(issuable) - Note.create_milestone_change_note( - issuable, issuable.project, current_user, issuable.milestone) - end - - def create_labels_note(issuable, added_labels, removed_labels) - Note.create_labels_change_note( - issuable, issuable.project, current_user, added_labels, removed_labels) - end -end diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb deleted file mode 100644 index c3ca04a43438563e6e8eebb2258bee6103a66f44..0000000000000000000000000000000000000000 --- a/app/services/issues/base_service.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Issues - class BaseService < ::IssuableBaseService - - def hook_data(issue, action) - issue_data = issue.to_hook_data(current_user) - issue_url = Gitlab::UrlBuilder.new(:issue).build(issue.id) - issue_data[:object_attributes].merge!(url: issue_url, action: action) - issue_data - end - - private - - def execute_hooks(issue, action = 'open') - issue_data = hook_data(issue, action) - issue.project.execute_hooks(issue_data, :issue_hooks) - issue.project.execute_services(issue_data, :issue_hooks) - end - end -end diff --git a/app/services/issues/bulk_update_service.rb b/app/services/issues/bulk_update_service.rb deleted file mode 100644 index eb07413ee9439e393b266049fc9aa2d3c9f1ec8e..0000000000000000000000000000000000000000 --- a/app/services/issues/bulk_update_service.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Issues - class BulkUpdateService < BaseService - def execute - issues_ids = params.delete(:issues_ids).split(",") - issue_params = params - - issue_params.delete(:state_event) unless issue_params[:state_event].present? - issue_params.delete(:milestone_id) unless issue_params[:milestone_id].present? - issue_params.delete(:assignee_id) unless issue_params[:assignee_id].present? - - issues = Issue.where(id: issues_ids) - issues.each do |issue| - next unless can?(current_user, :modify_issue, issue) - - Issues::UpdateService.new(issue.project, current_user, issue_params).execute(issue) - end - - { - count: issues.count, - success: !issues.count.zero? - } - end - end -end diff --git a/app/services/issues/close_service.rb b/app/services/issues/close_service.rb deleted file mode 100644 index f670019cc638a24d0dd2e666c8d6e1d1016fb36f..0000000000000000000000000000000000000000 --- a/app/services/issues/close_service.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Issues - class CloseService < Issues::BaseService - def execute(issue, commit = nil) - if issue.close - event_service.close_issue(issue, current_user) - create_note(issue, commit) - notification_service.close_issue(issue, current_user) - execute_hooks(issue, 'close') - end - - issue - end - - private - - def create_note(issue, current_commit) - Note.create_status_change_note(issue, issue.project, current_user, issue.state, current_commit) - end - end -end diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb deleted file mode 100644 index d5c17906a553f6fea262f1e83792b1dff2911dc0..0000000000000000000000000000000000000000 --- a/app/services/issues/create_service.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Issues - class CreateService < Issues::BaseService - def execute - label_params = params[:label_ids] - issue = project.issues.new(params.except(:label_ids)) - issue.author = current_user - - if issue.save - issue.update_attributes(label_ids: label_params) - notification_service.new_issue(issue, current_user) - event_service.open_issue(issue, current_user) - issue.create_cross_references!(issue.project, current_user) - execute_hooks(issue, 'open') - end - - issue - end - end -end diff --git a/app/services/issues/reopen_service.rb b/app/services/issues/reopen_service.rb deleted file mode 100644 index 1e5c398516dfa01982c7784b520a1ede7ad7270f..0000000000000000000000000000000000000000 --- a/app/services/issues/reopen_service.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Issues - class ReopenService < Issues::BaseService - def execute(issue) - if issue.reopen - event_service.reopen_issue(issue, current_user) - create_note(issue) - notification_service.reopen_issue(issue, current_user) - execute_hooks(issue, 'reopen') - end - - issue - end - - private - - def create_note(issue) - Note.create_status_change_note(issue, issue.project, current_user, issue.state, nil) - end - end -end diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb deleted file mode 100644 index 8f04a69287a787f07900319eafd7e538d6d388c8..0000000000000000000000000000000000000000 --- a/app/services/issues/update_service.rb +++ /dev/null @@ -1,47 +0,0 @@ -module Issues - class UpdateService < Issues::BaseService - def execute(issue) - state = params[:state_event] - - case state - when 'reopen' - Issues::ReopenService.new(project, current_user, {}).execute(issue) - when 'close' - Issues::CloseService.new(project, current_user, {}).execute(issue) - when 'task_check' - issue.update_nth_task(params[:task_num].to_i, true) - when 'task_uncheck' - issue.update_nth_task(params[:task_num].to_i, false) - end - - params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE - params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE - - old_labels = issue.labels.to_a - - if params.present? && issue.update_attributes(params.except(:state_event, - :task_num)) - issue.reset_events_cache - - if issue.labels != old_labels - create_labels_note( - issue, issue.labels - old_labels, old_labels - issue.labels) - end - - if issue.previous_changes.include?('milestone_id') - create_milestone_note(issue) - end - - if issue.previous_changes.include?('assignee_id') - create_assignee_note(issue) - notification_service.reassigned_issue(issue, current_user) - end - - issue.notice_added_references(issue.project, current_user) - execute_hooks(issue, 'update') - end - - issue - end - end -end diff --git a/app/services/merge_requests/auto_merge_service.rb b/app/services/merge_requests/auto_merge_service.rb deleted file mode 100644 index 378b39bb9d6dd2edcb4f9aa1b6bff8701c249ced..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/auto_merge_service.rb +++ /dev/null @@ -1,30 +0,0 @@ -module MergeRequests - # AutoMergeService class - # - # Do git merge in satellite and in case of success - # mark merge request as merged and execute all hooks and notifications - # Called when you do merge via GitLab UI - class AutoMergeService < BaseMergeService - def execute(merge_request, commit_message) - merge_request.lock_mr - - if Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message) - merge_request.merge - - create_merge_event(merge_request, current_user) - create_note(merge_request) - notification_service.merge_mr(merge_request, current_user) - execute_hooks(merge_request) - - true - else - merge_request.unlock_mr - false - end - rescue - merge_request.unlock_mr if merge_request.locked? - merge_request.mark_as_unmergeable - false - end - end -end diff --git a/app/services/merge_requests/base_merge_service.rb b/app/services/merge_requests/base_merge_service.rb deleted file mode 100644 index 9579573adf9fb9ff34c1b59f08668b46b11b04b2..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/base_merge_service.rb +++ /dev/null @@ -1,10 +0,0 @@ -module MergeRequests - class BaseMergeService < MergeRequests::BaseService - - private - - def create_merge_event(merge_request, current_user) - EventCreateService.new.merge_mr(merge_request, current_user) - end - end -end diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb deleted file mode 100644 index f6e1ae6f283e836cd3400393f26ee87c4c26f9af..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/base_service.rb +++ /dev/null @@ -1,24 +0,0 @@ -module MergeRequests - class BaseService < ::IssuableBaseService - - def create_note(merge_request) - Note.create_status_change_note(merge_request, merge_request.target_project, current_user, merge_request.state, nil) - end - - def hook_data(merge_request, action) - hook_data = merge_request.to_hook_data(current_user) - merge_request_url = Gitlab::UrlBuilder.new(:merge_request).build(merge_request.id) - hook_data[:object_attributes][:url] = merge_request_url - hook_data[:object_attributes][:action] = action - hook_data - end - - def execute_hooks(merge_request, action = 'open') - if merge_request.project - merge_data = hook_data(merge_request, action) - merge_request.project.execute_hooks(merge_data, :merge_request_hooks) - merge_request.project.execute_services(merge_data, :merge_request_hooks) - end - end - end -end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb deleted file mode 100644 index a44b91166e85c3fbf4fb737d12b561e21bd7409e..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/build_service.rb +++ /dev/null @@ -1,74 +0,0 @@ -module MergeRequests - class BuildService < MergeRequests::BaseService - def execute - merge_request = MergeRequest.new(params) - - # Set MR attributes - merge_request.can_be_created = false - merge_request.compare_failed = false - merge_request.compare_commits = [] - merge_request.compare_diffs = [] - merge_request.source_project = project unless merge_request.source_project - merge_request.target_project ||= (project.forked_from_project || project) - merge_request.target_branch ||= merge_request.target_project.default_branch - - unless merge_request.target_branch && merge_request.source_branch - return build_failed(merge_request, nil) - end - - compare_result = CompareService.new.execute( - current_user, - merge_request.source_project, - merge_request.source_branch, - merge_request.target_project, - merge_request.target_branch, - ) - - commits = compare_result.commits - - # At this point we decide if merge request can be created - # If we have at least one commit to merge -> creation allowed - if commits.present? - merge_request.compare_commits = Commit.decorate(commits) - merge_request.can_be_created = true - merge_request.compare_failed = false - - # Try to collect diff for merge request. - diffs = compare_result.diffs - - if diffs.present? - merge_request.compare_diffs = diffs - - elsif diffs == false - # satellite timeout return false - merge_request.can_be_created = false - merge_request.compare_failed = true - end - else - merge_request.can_be_created = false - merge_request.compare_failed = false - end - - commits = merge_request.compare_commits - if commits && commits.count == 1 - commit = commits.first - merge_request.title = commit.title - merge_request.description = commit.description.try(:strip) - else - merge_request.title = merge_request.source_branch.titleize.humanize - end - - merge_request - - rescue Gitlab::Satellite::BranchesWithoutParent - return build_failed(merge_request, "Selected branches have no common commit so they cannot be merged.") - end - - def build_failed(merge_request, message) - merge_request.errors.add(:base, message) unless message.nil? - merge_request.compare_commits = [] - merge_request.can_be_created = false - merge_request - end - end -end diff --git a/app/services/merge_requests/close_service.rb b/app/services/merge_requests/close_service.rb deleted file mode 100644 index 47454f9f0c214f52932a55da53eb6bc8fdf22f8a..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/close_service.rb +++ /dev/null @@ -1,18 +0,0 @@ -module MergeRequests - class CloseService < MergeRequests::BaseService - def execute(merge_request, commit = nil) - # If we close MergeRequest we want to ignore validation - # so we can close broken one (Ex. fork project removed) - merge_request.allow_broken = true - - if merge_request.close - event_service.close_mr(merge_request, current_user) - create_note(merge_request) - notification_service.close_mr(merge_request, current_user) - execute_hooks(merge_request, 'close') - end - - merge_request - end - end -end diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb deleted file mode 100644 index ca8d80f6c0c128a3049f451f4a83399c7f8e4351..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/create_service.rb +++ /dev/null @@ -1,21 +0,0 @@ -module MergeRequests - class CreateService < MergeRequests::BaseService - def execute - label_params = params[:label_ids] - merge_request = MergeRequest.new(params.except(:label_ids)) - merge_request.source_project = project - merge_request.target_project ||= project - merge_request.author = current_user - - if merge_request.save - merge_request.update_attributes(label_ids: label_params) - event_service.open_mr(merge_request, current_user) - notification_service.new_merge_request(merge_request, current_user) - merge_request.create_cross_references!(merge_request.project, current_user) - execute_hooks(merge_request) - end - - merge_request - end - end -end diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb deleted file mode 100644 index 327ead4ff3fe1fdb869aa415a48ee54ab9a222a5..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/merge_service.rb +++ /dev/null @@ -1,22 +0,0 @@ -module MergeRequests - # MergeService class - # - # Mark existing merge request as merged - # and execute all hooks and notifications - # Called when you do merge via command line and push code - # to target branch - class MergeService < BaseMergeService - def execute(merge_request, commit_message) - merge_request.merge - - create_merge_event(merge_request, current_user) - create_note(merge_request) - notification_service.merge_mr(merge_request, current_user) - execute_hooks(merge_request, 'merge') - - true - rescue - false - end - end -end diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb deleted file mode 100644 index e9b526d1fb7bc192a5fd33baafe45486d17895e2..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/refresh_service.rb +++ /dev/null @@ -1,94 +0,0 @@ -module MergeRequests - class RefreshService < MergeRequests::BaseService - def execute(oldrev, newrev, ref) - return true unless Gitlab::Git.branch_ref?(ref) - - @oldrev, @newrev = oldrev, newrev - @branch_name = Gitlab::Git.ref_name(ref) - @fork_merge_requests = @project.fork_merge_requests.opened - @commits = @project.repository.commits_between(oldrev, newrev) - - close_merge_requests - reload_merge_requests - comment_mr_with_commits - - true - end - - private - - # Collect open merge requests that target same branch we push into - # and close if push to master include last commit from merge request - # We need this to close(as merged) merge requests that were merged into - # target branch manually - def close_merge_requests - commit_ids = @commits.map(&:id) - merge_requests = @project.merge_requests.opened.where(target_branch: @branch_name).to_a - merge_requests = merge_requests.select(&:last_commit) - - merge_requests = merge_requests.select do |merge_request| - commit_ids.include?(merge_request.last_commit.id) - end - - - merge_requests.uniq.select(&:source_project).each do |merge_request| - MergeRequests::MergeService. - new(merge_request.target_project, @current_user). - execute(merge_request, nil) - end - end - - def force_push? - Gitlab::ForcePushCheck.force_push?(@project, @oldrev, @newrev) - end - - # Refresh merge request diff if we push to source or target branch of merge request - # Note: we should update merge requests from forks too - def reload_merge_requests - merge_requests = @project.merge_requests.opened.by_branch(@branch_name).to_a - merge_requests += @fork_merge_requests.by_branch(@branch_name).to_a - merge_requests = filter_merge_requests(merge_requests) - - merge_requests.each do |merge_request| - - if merge_request.source_branch == @branch_name || force_push? - merge_request.reload_code - merge_request.mark_as_unchecked - else - mr_commit_ids = merge_request.commits.map(&:id) - push_commit_ids = @commits.map(&:id) - matches = mr_commit_ids & push_commit_ids - - if matches.any? - merge_request.reload_code - merge_request.mark_as_unchecked - else - merge_request.mark_as_unchecked - end - end - end - end - - # Add comment about pushing new commits to merge requests - def comment_mr_with_commits - merge_requests = @project.origin_merge_requests.opened.where(source_branch: @branch_name).to_a - merge_requests += @fork_merge_requests.where(source_branch: @branch_name).to_a - merge_requests = filter_merge_requests(merge_requests) - - merge_requests.each do |merge_request| - mr_commit_ids = Set.new(merge_request.commits.map(&:id)) - - new_commits, existing_commits = @commits.partition do |commit| - mr_commit_ids.include?(commit.id) - end - - Note.create_new_commits_note(merge_request, merge_request.project, - @current_user, new_commits, existing_commits, @oldrev) - end - end - - def filter_merge_requests(merge_requests) - merge_requests.uniq.select(&:source_project) - end - end -end diff --git a/app/services/merge_requests/reopen_service.rb b/app/services/merge_requests/reopen_service.rb deleted file mode 100644 index 8279ad2001b07e42c2a4faa8ab64c4ff797c2b96..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/reopen_service.rb +++ /dev/null @@ -1,16 +0,0 @@ -module MergeRequests - class ReopenService < MergeRequests::BaseService - def execute(merge_request) - if merge_request.reopen - event_service.reopen_mr(merge_request, current_user) - create_note(merge_request) - notification_service.reopen_mr(merge_request, current_user) - execute_hooks(merge_request, 'reopen') - merge_request.reload_code - merge_request.mark_as_unchecked - end - - merge_request - end - end -end diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb deleted file mode 100644 index 23af2656c375de3bad8a399b70ad05f7ee540a35..0000000000000000000000000000000000000000 --- a/app/services/merge_requests/update_service.rb +++ /dev/null @@ -1,60 +0,0 @@ -require_relative 'base_service' -require_relative 'reopen_service' -require_relative 'close_service' - -module MergeRequests - class UpdateService < MergeRequests::BaseService - def execute(merge_request) - # We dont allow change of source/target projects - # after merge request was created - params.except!(:source_project_id) - params.except!(:target_project_id) - - state = params[:state_event] - - case state - when 'reopen' - MergeRequests::ReopenService.new(project, current_user, {}).execute(merge_request) - when 'close' - MergeRequests::CloseService.new(project, current_user, {}).execute(merge_request) - when 'task_check' - merge_request.update_nth_task(params[:task_num].to_i, true) - when 'task_uncheck' - merge_request.update_nth_task(params[:task_num].to_i, false) - end - - params[:assignee_id] = "" if params[:assignee_id] == IssuableFinder::NONE - params[:milestone_id] = "" if params[:milestone_id] == IssuableFinder::NONE - - old_labels = merge_request.labels.to_a - - if params.present? && merge_request.update_attributes( - params.except(:state_event, :task_num) - ) - merge_request.reset_events_cache - - if merge_request.labels != old_labels - create_labels_note( - merge_request, - merge_request.labels - old_labels, - old_labels - merge_request.labels - ) - end - - if merge_request.previous_changes.include?('milestone_id') - create_milestone_note(merge_request) - end - - if merge_request.previous_changes.include?('assignee_id') - create_assignee_note(merge_request) - notification_service.reassigned_merge_request(merge_request, current_user) - end - - merge_request.notice_added_references(merge_request.project, current_user) - execute_hooks(merge_request, 'update') - end - - merge_request - end - end -end diff --git a/app/services/milestones/base_service.rb b/app/services/milestones/base_service.rb deleted file mode 100644 index 176ab9f1ab5ca909bb6e2cd424a7e61586f63146..0000000000000000000000000000000000000000 --- a/app/services/milestones/base_service.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Milestones - class BaseService < ::BaseService - end -end diff --git a/app/services/milestones/close_service.rb b/app/services/milestones/close_service.rb deleted file mode 100644 index 608fc49d7669b31493f2f24cd60eb2c0eb0cb074..0000000000000000000000000000000000000000 --- a/app/services/milestones/close_service.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Milestones - class CloseService < Milestones::BaseService - def execute(milestone) - if milestone.close - event_service.close_milestone(milestone, current_user) - end - - milestone - end - end -end diff --git a/app/services/milestones/create_service.rb b/app/services/milestones/create_service.rb deleted file mode 100644 index b8e08c9f1eb167e97f496f359819b5c013c1aeb5..0000000000000000000000000000000000000000 --- a/app/services/milestones/create_service.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Milestones - class CreateService < Milestones::BaseService - def execute - milestone = project.milestones.new(params) - - if milestone.save - event_service.open_milestone(milestone, current_user) - end - - milestone - end - end -end diff --git a/app/services/milestones/group_service.rb b/app/services/milestones/group_service.rb deleted file mode 100644 index 11d702f1e7b33753f1ccc4e14294aee7e3b21a15..0000000000000000000000000000000000000000 --- a/app/services/milestones/group_service.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Milestones - class GroupService < Milestones::BaseService - def initialize(project_milestones) - @project_milestones = project_milestones.group_by(&:title) - end - - def execute - build(@project_milestones) - end - - def milestone(title) - if title - group_milestone = @project_milestones[title].group_by(&:title) - build(group_milestone).first - else - nil - end - end - - private - - def build(milestone) - milestone.map{ |title, milestones| GroupMilestone.new(title, milestones) } - end - end -end diff --git a/app/services/milestones/reopen_service.rb b/app/services/milestones/reopen_service.rb deleted file mode 100644 index 573f9ee5c2100c6e4318f904215c96f1c5a4338e..0000000000000000000000000000000000000000 --- a/app/services/milestones/reopen_service.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Milestones - class ReopenService < Milestones::BaseService - def execute(milestone) - if milestone.activate - event_service.reopen_milestone(milestone, current_user) - end - - milestone - end - end -end diff --git a/app/services/milestones/update_service.rb b/app/services/milestones/update_service.rb deleted file mode 100644 index ed64847f429590bec4962afd3343054726ec3d27..0000000000000000000000000000000000000000 --- a/app/services/milestones/update_service.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Milestones - class UpdateService < Milestones::BaseService - def execute(milestone) - state = params[:state_event] - - case state - when 'activate' - Milestones::ReopenService.new(project, current_user, {}).execute(milestone) - when 'close' - Milestones::CloseService.new(project, current_user, {}).execute(milestone) - end - - if params.present? - milestone.update_attributes(params.except(:state_event)) - end - - milestone - end - end -end diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb deleted file mode 100644 index e969061f229d8a8ee6ce266cdf9a88a50c79af45..0000000000000000000000000000000000000000 --- a/app/services/notes/create_service.rb +++ /dev/null @@ -1,38 +0,0 @@ -module Notes - class CreateService < BaseService - def execute - note = project.notes.new(params) - note.author = current_user - note.system = false - - if note.save - notification_service.new_note(note) - - # Skip system notes, like status changes and cross-references. - unless note.system - event_service.leave_note(note, note.author) - - # Create a cross-reference note if this Note contains GFM that names an - # issue, merge request, or commit. - note.references.each do |mentioned| - Note.create_cross_reference_note(mentioned, note.noteable, note.author, note.project) - end - - execute_hooks(note) - end - end - - note - end - - def hook_data(note) - Gitlab::NoteDataBuilder.build(note, current_user) - end - - def execute_hooks(note) - note_data = hook_data(note) - # TODO: Support Webhooks - note.project.execute_services(note_data, :note_hooks) - end - end -end diff --git a/app/services/notes/update_service.rb b/app/services/notes/update_service.rb deleted file mode 100644 index 63431b82471ee5e16a9b1d1283dccc85d6ac957a..0000000000000000000000000000000000000000 --- a/app/services/notes/update_service.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Notes - class UpdateService < BaseService - def execute - note = project.notes.find(params[:note_id]) - note.note = params[:note] - if note.save - notification_service.new_note(note) - - # Skip system notes, like status changes and cross-references. - unless note.system - event_service.leave_note(note, note.author) - - # Create a cross-reference note if this Note contains GFM that - # names an issue, merge request, or commit. - note.references.each do |mentioned| - Note.create_cross_reference_note(mentioned, note.noteable, - note.author, note.project) - end - end - end - - note - end - end -end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb deleted file mode 100644 index cfed7964c37e8626810125fae29350dd9f58a14d..0000000000000000000000000000000000000000 --- a/app/services/notification_service.rb +++ /dev/null @@ -1,432 +0,0 @@ -# NotificationService class -# -# Used for notifying users with emails about different events -# -# Ex. -# NotificationService.new.new_issue(issue, current_user) -# -class NotificationService - # Always notify user about ssh key added - # only if ssh key is not deploy key - # - # This is security email so it will be sent - # even if user disabled notifications - def new_key(key) - if key.user - mailer.new_ssh_key_email(key.id) - end - end - - # Always notify user about email added to profile - def new_email(email) - if email.user - mailer.new_email_email(email.id) - end - end - - # When create an issue we should send next emails: - # - # * issue assignee if their notification level is not Disabled - # * project team members with notification level higher then Participating - # - def new_issue(issue, current_user) - new_resource_email(issue, issue.project, 'new_issue_email') - end - - # When we close an issue we should send next emails: - # - # * issue author if their notification level is not Disabled - # * issue assignee if their notification level is not Disabled - # * project team members with notification level higher then Participating - # - def close_issue(issue, current_user) - close_resource_email(issue, issue.project, current_user, 'closed_issue_email') - end - - # When we reassign an issue we should send next emails: - # - # * issue old assignee if their notification level is not Disabled - # * issue new assignee if their notification level is not Disabled - # - def reassigned_issue(issue, current_user) - reassign_resource_email(issue, issue.project, current_user, 'reassigned_issue_email') - end - - - # When create a merge request we should send next emails: - # - # * mr assignee if their notification level is not Disabled - # - def new_merge_request(merge_request, current_user) - new_resource_email(merge_request, merge_request.target_project, 'new_merge_request_email') - end - - # When we reassign a merge_request we should send next emails: - # - # * merge_request old assignee if their notification level is not Disabled - # * merge_request assignee if their notification level is not Disabled - # - def reassigned_merge_request(merge_request, current_user) - reassign_resource_email(merge_request, merge_request.target_project, current_user, 'reassigned_merge_request_email') - end - - # When we close a merge request we should send next emails: - # - # * merge_request author if their notification level is not Disabled - # * merge_request assignee if their notification level is not Disabled - # * project team members with notification level higher then Participating - # - def close_mr(merge_request, current_user) - close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email') - end - - def reopen_issue(issue, current_user) - reopen_resource_email(issue, issue.project, current_user, 'issue_status_changed_email', 'reopened') - end - - # When we merge a merge request we should send next emails: - # - # * merge_request author if their notification level is not Disabled - # * merge_request assignee if their notification level is not Disabled - # * project team members with notification level higher then Participating - # - def merge_mr(merge_request, current_user) - recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project) - recipients = add_subscribed_users(recipients, merge_request) - recipients = reject_unsubscribed_users(recipients, merge_request) - recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq - recipients.delete(current_user) - - recipients.each do |recipient| - mailer.merged_merge_request_email(recipient.id, merge_request.id, current_user.id) - end - end - - def reopen_mr(merge_request, current_user) - reopen_resource_email(merge_request, merge_request.target_project, current_user, 'merge_request_status_email', 'reopened') - end - - # Notify new user with email after creation - def new_user(user, token = nil) - # Don't email omniauth created users - mailer.new_user_email(user.id, token) unless user.identities.any? - end - - # Notify users on new note in system - # - # TODO: split on methods and refactor - # - def new_note(note) - return true unless note.noteable_type.present? - - # ignore gitlab service messages - return true if note.note.start_with?('Status changed to closed') - return true if note.cross_reference? && note.system == true - - target = note.noteable - - recipients = [] - - if note.commit_id.present? - recipients << note.commit_author - end - - # Add all users participating in the thread (author, assignee, comment authors) - participants = - if target.respond_to?(:participants) - target.participants - elsif target.is_a?(Commit) - author_ids = Note.for_commit_id(target.id).pluck(:author_id).uniq - User.where(id: author_ids) - else - note.mentioned_users - end - recipients = recipients.concat(participants) - - # Merge project watchers - recipients = recipients.concat(project_watchers(note.project)).compact.uniq - - # Reject users with Mention notification level, except those mentioned in _this_ note. - recipients = reject_mention_users(recipients - note.mentioned_users, note.project) - recipients = recipients + note.mentioned_users - - # Reject mutes users - recipients = reject_muted_users(recipients, note.project) - - recipients = add_subscribed_users(recipients, note.noteable) - - recipients = reject_unsubscribed_users(recipients, note.noteable) - - # Reject author - recipients.delete(note.author) - - # build notify method like 'note_commit_email' - notify_method = "note_#{note.noteable_type.underscore}_email".to_sym - - recipients.each do |recipient| - mailer.send(notify_method, recipient.id, note.id) - end - end - - def invite_project_member(project_member, token) - mailer.project_member_invited_email(project_member.id, token) - end - - def accept_project_invite(project_member) - mailer.project_invite_accepted_email(project_member.id) - end - - def decline_project_invite(project_member) - mailer.project_invite_declined_email(project_member.project.id, project_member.invite_email, project_member.access_level, project_member.created_by_id) - end - - def new_project_member(project_member) - mailer.project_access_granted_email(project_member.id) - end - - def update_project_member(project_member) - mailer.project_access_granted_email(project_member.id) - end - - def invite_group_member(group_member, token) - mailer.group_member_invited_email(group_member.id, token) - end - - def accept_group_invite(group_member) - mailer.group_invite_accepted_email(group_member.id) - end - - def decline_group_invite(group_member) - mailer.group_invite_declined_email(group_member.group.id, group_member.invite_email, group_member.access_level, group_member.created_by_id) - end - - def new_group_member(group_member) - mailer.group_access_granted_email(group_member.id) - end - - def update_group_member(group_member) - mailer.group_access_granted_email(group_member.id) - end - - def project_was_moved(project) - recipients = project.team.members - recipients = reject_muted_users(recipients, project) - - recipients.each do |recipient| - mailer.project_was_moved_email(project.id, recipient.id) - end - end - - protected - - # Get project users with WATCH notification level - def project_watchers(project) - project_members = project_member_notification(project) - - users_with_project_level_global = project_member_notification(project, Notification::N_GLOBAL) - users_with_group_level_global = group_member_notification(project, Notification::N_GLOBAL) - users = users_with_global_level_watch([users_with_project_level_global, users_with_group_level_global].flatten.uniq) - - users_with_project_setting = select_project_member_setting(project, users_with_project_level_global, users) - users_with_group_setting = select_group_member_setting(project, project_members, users_with_group_level_global, users) - - User.where(id: users_with_project_setting.concat(users_with_group_setting).uniq).to_a - end - - def project_member_notification(project, notification_level=nil) - project_members = project.project_members - - if notification_level - project_members.where(notification_level: notification_level).pluck(:user_id) - else - project_members.pluck(:user_id) - end - end - - def group_member_notification(project, notification_level) - if project.group - project.group.group_members.where(notification_level: notification_level).pluck(:user_id) - else - [] - end - end - - def users_with_global_level_watch(ids) - User.where( - id: ids, - notification_level: Notification::N_WATCH - ).pluck(:id) - end - - # Build a list of users based on project notifcation settings - def select_project_member_setting(project, global_setting, users_global_level_watch) - users = project_member_notification(project, Notification::N_WATCH) - - # If project setting is global, add to watch list if global setting is watch - global_setting.each do |user_id| - if users_global_level_watch.include?(user_id) - users << user_id - end - end - - users - end - - # Build a list of users based on group notification settings - def select_group_member_setting(project, project_members, global_setting, users_global_level_watch) - uids = group_member_notification(project, Notification::N_WATCH) - - # Group setting is watch, add to users list if user is not project member - users = [] - uids.each do |user_id| - if project_members.exclude?(user_id) - users << user_id - end - end - - # Group setting is global, add to users list if global setting is watch - global_setting.each do |user_id| - if project_members.exclude?(user_id) && users_global_level_watch.include?(user_id) - users << user_id - end - end - - users - end - - # Remove users with disabled notifications from array - # Also remove duplications and nil recipients - def reject_muted_users(users, project = nil) - users = users.to_a.compact.uniq - users = users.reject(&:blocked?) - - users.reject do |user| - next user.notification.disabled? unless project - - member = project.project_members.find_by(user_id: user.id) - - if !member && project.group - member = project.group.group_members.find_by(user_id: user.id) - end - - # reject users who globally disabled notification and has no membership - next user.notification.disabled? unless member - - # reject users who disabled notification in project - next true if member.notification.disabled? - - # reject users who have N_GLOBAL in project and disabled in global settings - member.notification.global? && user.notification.disabled? - end - end - - # Remove users with notification level 'Mentioned' - def reject_mention_users(users, project = nil) - users = users.to_a.compact.uniq - - users.reject do |user| - next user.notification.mention? unless project - - member = project.project_members.find_by(user_id: user.id) - - if !member && project.group - member = project.group.group_members.find_by(user_id: user.id) - end - - # reject users who globally set mention notification and has no membership - next user.notification.mention? unless member - - # reject users who set mention notification in project - next true if member.notification.mention? - - # reject users who have N_MENTION in project and disabled in global settings - member.notification.global? && user.notification.mention? - end - end - - def reject_unsubscribed_users(recipients, target) - return recipients unless target.respond_to? :subscriptions - - recipients.reject do |user| - subscription = target.subscriptions.find_by_user_id(user.id) - subscription && !subscription.subscribed - end - end - - def add_subscribed_users(recipients, target) - return recipients unless target.respond_to? :subscriptions - - subscriptions = target.subscriptions - - if subscriptions.any? - recipients + subscriptions.where(subscribed: true).map(&:user) - else - recipients - end - end - - def new_resource_email(target, project, method) - recipients = build_recipients(target, project) - recipients.delete(target.author) - - recipients.each do |recipient| - mailer.send(method, recipient.id, target.id) - end - end - - def close_resource_email(target, project, current_user, method) - recipients = build_recipients(target, project) - recipients.delete(current_user) - - recipients.each do |recipient| - mailer.send(method, recipient.id, target.id, current_user.id) - end - end - - def reassign_resource_email(target, project, current_user, method) - assignee_id_was = previous_record(target, "assignee_id") - recipients = build_recipients(target, project) - recipients.delete(current_user) - - recipients.each do |recipient| - mailer.send(method, recipient.id, target.id, assignee_id_was, current_user.id) - end - end - - def reopen_resource_email(target, project, current_user, method, status) - recipients = build_recipients(target, project) - recipients.delete(current_user) - - recipients.each do |recipient| - mailer.send(method, recipient.id, target.id, status, current_user.id) - end - end - - def build_recipients(target, project) - recipients = - if target.respond_to?(:participants) - target.participants - else - [target.author, target.assignee] - end - - recipients = reject_muted_users(recipients, project) - recipients = reject_mention_users(recipients, project) - recipients = add_subscribed_users(recipients, target) - recipients = recipients.concat(project_watchers(project)).uniq - recipients = reject_unsubscribed_users(recipients, target) - recipients - end - - def mailer - Notify.delay - end - - def previous_record(object, attribute) - if object && attribute - if object.previous_changes.include?(attribute) - object.previous_changes[attribute].first - end - end - end -end diff --git a/app/services/oauth2/access_token_validation_service.rb b/app/services/oauth2/access_token_validation_service.rb deleted file mode 100644 index 6194f6ce91eb334c30a14e9beba31cd63e4060ec..0000000000000000000000000000000000000000 --- a/app/services/oauth2/access_token_validation_service.rb +++ /dev/null @@ -1,41 +0,0 @@ -module Oauth2::AccessTokenValidationService - # Results: - VALID = :valid - EXPIRED = :expired - REVOKED = :revoked - INSUFFICIENT_SCOPE = :insufficient_scope - - class << self - def validate(token, scopes: []) - if token.expired? - return EXPIRED - - elsif token.revoked? - return REVOKED - - elsif !self.sufficient_scope?(token, scopes) - return INSUFFICIENT_SCOPE - - else - return VALID - end - end - - protected - # True if the token's scope is a superset of required scopes, - # or the required scopes is empty. - def sufficient_scope?(token, scopes) - if scopes.blank? - # if no any scopes required, the scopes of token is sufficient. - return true - else - # If there are scopes required, then check whether - # the set of authorized scopes is a superset of the set of required scopes - required_scopes = Set.new(scopes) - authorized_scopes = Set.new(token.scopes) - - return authorized_scopes >= required_scopes - end - end - end -end diff --git a/app/services/projects/autocomplete_service.rb b/app/services/projects/autocomplete_service.rb deleted file mode 100644 index 7408e09ed1e9df60df177b33cade2521db187cda..0000000000000000000000000000000000000000 --- a/app/services/projects/autocomplete_service.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Projects - class AutocompleteService < BaseService - def initialize(project) - @project = project - end - - def issues - @project.issues.opened.select([:iid, :title]) - end - - def merge_requests - @project.merge_requests.opened.select([:iid, :title]) - end - end -end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb deleted file mode 100644 index a7afcf8f64b94420ad2b82fa617ed92e1d5c8a45..0000000000000000000000000000000000000000 --- a/app/services/projects/create_service.rb +++ /dev/null @@ -1,96 +0,0 @@ -module Projects - class CreateService < BaseService - def initialize(user, params) - @current_user, @params = user, params.dup - end - - def execute - @project = Project.new(params) - - # Make sure that the user is allowed to use the specified visibility - # level - unless Gitlab::VisibilityLevel.allowed_for?(current_user, - params[:visibility_level]) - deny_visibility_level(@project) - return @project - end - - # Set project name from path - if @project.name.present? && @project.path.present? - # if both name and path set - everything is ok - elsif @project.path.present? - # Set project name from path - @project.name = @project.path.dup - elsif @project.name.present? - # For compatibility - set path from name - # TODO: remove this in 8.0 - @project.path = @project.name.dup.parameterize - end - - # get namespace id - namespace_id = params[:namespace_id] - - if namespace_id - # Find matching namespace and check if it allowed - # for current user if namespace_id passed. - unless allowed_namespace?(current_user, namespace_id) - @project.namespace_id = nil - deny_namespace - return @project - end - else - # Set current user namespace if namespace_id is nil - @project.namespace_id = current_user.namespace_id - end - - @project.creator = current_user - - Project.transaction do - @project.save - - unless @project.import? - unless @project.create_repository - raise 'Failed to create repository' - end - end - end - - after_create_actions if @project.persisted? - - @project - rescue => ex - @project.errors.add(:base, "Can't save project. Please try again later") - @project - end - - protected - - def deny_namespace - @project.errors.add(:namespace, "is not valid") - end - - def allowed_namespace?(user, namespace_id) - namespace = Namespace.find_by(id: namespace_id) - current_user.can?(:create_projects, namespace) - end - - def after_create_actions - log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"") - - @project.create_wiki if @project.wiki_enabled? - - event_service.create_project(@project, current_user) - system_hook_service.execute_hooks_for(@project, :create) - - unless @project.group - @project.team << [current_user, :master, current_user] - end - - @project.update_column(:last_activity_at, @project.created_at) - - if @project.import? - @project.import_start - end - end - end -end diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb deleted file mode 100644 index 7e1d753b021d9cdded104c658f7b5d4d0b5abf61..0000000000000000000000000000000000000000 --- a/app/services/projects/destroy_service.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Projects - class DestroyService < BaseService - def execute - return false unless can?(current_user, :remove_project, project) - - project.team.truncate - project.repository.expire_cache unless project.empty_repo? - - if project.destroy - GitlabShellWorker.perform_async( - :remove_repository, - project.path_with_namespace - ) - - GitlabShellWorker.perform_async( - :remove_repository, - project.path_with_namespace + ".wiki" - ) - - project.satellite.destroy - - log_info("Project \"#{project.name}\" was removed") - system_hook_service.execute_hooks_for(project, :destroy) - true - end - end - end -end diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb deleted file mode 100644 index 1e4deb6ed39babde42725d703f7206fd2c14011a..0000000000000000000000000000000000000000 --- a/app/services/projects/fork_service.rb +++ /dev/null @@ -1,66 +0,0 @@ -module Projects - class ForkService < BaseService - include Gitlab::ShellAdapter - - def execute - @from_project = @project - - project_params = { - visibility_level: @from_project.visibility_level, - description: @from_project.description, - } - - project = Project.new(project_params) - project.name = @from_project.name - project.path = @from_project.path - project.creator = @current_user - if @from_project.avatar.present? && @from_project.avatar.image? - project.avatar = @from_project.avatar - end - - if namespace = @params[:namespace] - project.namespace = namespace - else - project.namespace = @current_user.namespace - end - - unless @current_user.can?(:create_projects, project.namespace) - project.errors.add(:namespace, 'insufficient access rights') - return project - end - - # If the project cannot save, we do not want to trigger the project destroy - # as this can have the side effect of deleting a repo attached to an existing - # project with the same name and namespace - if project.valid? - begin - Project.transaction do - #First save the DB entries as they can be rolled back if the repo fork fails - project.build_forked_project_link(forked_to_project_id: project.id, forked_from_project_id: @from_project.id) - if project.save - project.team << [@current_user, :master, @current_user] - end - - #Now fork the repo - unless gitlab_shell.fork_repository(@from_project.path_with_namespace, project.namespace.path) - raise 'forking failed in gitlab-shell' - end - - project.ensure_satellite_exists - end - - if @from_project.gitlab_ci? - ForkRegistrationWorker.perform_async(@from_project.id, project.id, @current_user.private_token) - end - rescue => ex - project.errors.add(:base, 'Fork transaction failed.') - project.destroy - end - else - project.errors.add(:base, 'Invalid fork destination') - end - - project - end - end -end diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb deleted file mode 100644 index ae6260bcdab714411401a2b1ea9b876d1490532e..0000000000000000000000000000000000000000 --- a/app/services/projects/participants_service.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Projects - class ParticipantsService < BaseService - def execute(note_type, note_id) - participating = - if note_type && note_id - participants_in(note_type, note_id) - else - [] - end - project_members = sorted(project.team.members) - participants = all_members + groups + project_members + participating - participants.uniq - end - - def participants_in(type, id) - users = case type - when "Issue" - issue = project.issues.find_by_iid(id) - issue ? issue.participants(current_user) : [] - when "MergeRequest" - merge_request = project.merge_requests.find_by_iid(id) - merge_request ? merge_request.participants(current_user) : [] - when "Commit" - author_ids = Note.for_commit_id(id).pluck(:author_id).uniq - User.where(id: author_ids) - else - [] - end - sorted(users) - end - - def sorted(users) - users.uniq.to_a.compact.sort_by(&:username).map do |user| - { username: user.username, name: user.name } - end - end - - def groups - current_user.authorized_groups.sort_by(&:path).map do |group| - count = group.users.count - { username: group.path, name: "#{group.name} (#{count})" } - end - end - - def all_members - count = project.team.members.flatten.count - [{ username: "all", name: "All Project and Group Members (#{count})" }] - end - end -end diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb deleted file mode 100644 index 489e03bd5ef6c256b346e257f5485e3dd72f6bc0..0000000000000000000000000000000000000000 --- a/app/services/projects/transfer_service.rb +++ /dev/null @@ -1,74 +0,0 @@ -# Projects::TransferService class -# -# Used for transfer project to another namespace -# -# Ex. -# # Move projects to namespace with ID 17 by user -# Projects::TransferService.new(project, user, namespace_id: 17).execute -# -module Projects - class TransferService < BaseService - include Gitlab::ShellAdapter - class TransferError < StandardError; end - - def execute - namespace_id = params[:new_namespace_id] - namespace = Namespace.find_by(id: namespace_id) - - if allowed_transfer?(current_user, project, namespace) - transfer(project, namespace) - else - project.errors.add(:namespace, 'is invalid') - false - end - rescue Projects::TransferService::TransferError => ex - project.reload - project.errors.add(:namespace_id, ex.message) - false - end - - def transfer(project, new_namespace) - Project.transaction do - old_path = project.path_with_namespace - new_path = File.join(new_namespace.try(:path) || '', project.path) - - if Project.where(path: project.path, namespace_id: new_namespace.try(:id)).present? - raise TransferError.new("Project with same path in target namespace already exists") - end - - # Remove old satellite - project.satellite.destroy - - # Apply new namespace id - project.namespace = new_namespace - project.save! - - # Notifications - project.send_move_instructions - - # Move main repository - unless gitlab_shell.mv_repository(old_path, new_path) - raise TransferError.new('Cannot move project') - end - - # Move wiki repo also if present - gitlab_shell.mv_repository("#{old_path}.wiki", "#{new_path}.wiki") - - # Create a new satellite (reload project from DB) - Project.find(project.id).ensure_satellite_exists - - # clear project cached events - project.reset_events_cache - - true - end - end - - def allowed_transfer?(current_user, project, namespace) - namespace && - can?(current_user, :change_namespace, project) && - namespace.id != project.namespace_id && - current_user.can?(:create_projects, namespace) - end - end -end diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb deleted file mode 100644 index 69bdd045ddfeece023c92821cd7d7cdb3cd89853..0000000000000000000000000000000000000000 --- a/app/services/projects/update_service.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Projects - class UpdateService < BaseService - def execute - # check that user is allowed to set specified visibility_level - new_visibility = params[:visibility_level] - if new_visibility && new_visibility.to_i != project.visibility_level - unless can?(current_user, :change_visibility_level, project) && - Gitlab::VisibilityLevel.allowed_for?(current_user, new_visibility) - deny_visibility_level(project, new_visibility) - return project - end - end - - new_branch = params[:default_branch] - - if project.repository.exists? && new_branch && new_branch != project.default_branch - project.change_head(new_branch) - end - - if project.update_attributes(params.except(:default_branch)) - if project.previous_changes.include?('path') - project.rename_repo - end - end - end - end -end diff --git a/app/services/projects/upload_service.rb b/app/services/projects/upload_service.rb deleted file mode 100644 index 992a7a7a1dc7f213abe3ff0c6fd481378b9f08ea..0000000000000000000000000000000000000000 --- a/app/services/projects/upload_service.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Projects - class UploadService < BaseService - def initialize(project, file) - @project, @file = project, file - end - - def execute - return nil unless @file and @file.size <= max_attachment_size - - uploader = FileUploader.new(@project) - uploader.store!(@file) - - filename = uploader.image? ? uploader.file.basename : uploader.file.filename - - { - 'alt' => filename, - 'url' => uploader.secure_url, - 'is_image' => uploader.image? - } - end - - private - - def max_attachment_size - current_application_settings.max_attachment_size.megabytes.to_i - end - end -end diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb deleted file mode 100644 index 0bcc50c81a7217f266191ea3a82cb080bee1d48d..0000000000000000000000000000000000000000 --- a/app/services/search/global_service.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Search - class GlobalService - attr_accessor :current_user, :params - - def initialize(user, params) - @current_user, @params = user, params.dup - end - - def execute - group = Group.find_by(id: params[:group_id]) if params[:group_id].present? - projects = ProjectsFinder.new.execute(current_user) - projects = projects.where(namespace_id: group.id) if group - project_ids = projects.pluck(:id) - - Gitlab::SearchResults.new(project_ids, params[:search]) - end - end -end diff --git a/app/services/search/project_service.rb b/app/services/search/project_service.rb deleted file mode 100644 index f630c0a37903a374f9edd0aa5ee11a3c68b45b8d..0000000000000000000000000000000000000000 --- a/app/services/search/project_service.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Search - class ProjectService - attr_accessor :project, :current_user, :params - - def initialize(project, user, params) - @project, @current_user, @params = project, user, params.dup - end - - def execute - Gitlab::ProjectSearchResults.new(project.id, - params[:search], - params[:repository_ref]) - end - end -end diff --git a/app/services/search/snippet_service.rb b/app/services/search/snippet_service.rb deleted file mode 100644 index 8ca0877321d759efbb7e1e9ec1f3aba6a5b45ac6..0000000000000000000000000000000000000000 --- a/app/services/search/snippet_service.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Search - class SnippetService - attr_accessor :current_user, :params - - def initialize(user, params) - @current_user, @params = user, params.dup - end - - def execute - snippet_ids = Snippet.accessible_to(current_user).pluck(:id) - Gitlab::SnippetSearchResults.new(snippet_ids, params[:search]) - end - end -end diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb deleted file mode 100644 index c5d0b08845ba79d1c3131f47d3b8a6ba10e9d0c6..0000000000000000000000000000000000000000 --- a/app/services/system_hooks_service.rb +++ /dev/null @@ -1,98 +0,0 @@ -class SystemHooksService - def execute_hooks_for(model, event) - execute_hooks(build_event_data(model, event)) - end - - private - - def execute_hooks(data) - SystemHook.all.each do |sh| - async_execute_hook sh, data - end - end - - def async_execute_hook(hook, data) - Sidekiq::Client.enqueue(SystemHookWorker, hook.id, data) - end - - def build_event_data(model, event) - data = { - event_name: build_event_name(model, event), - created_at: model.created_at.xmlschema - } - - case model - when Key - data.merge!( - key: model.key, - id: model.id - ) - if model.user - data.merge!( - username: model.user.username - ) - end - when Project - owner = model.owner - - data.merge!({ - name: model.name, - path: model.path, - path_with_namespace: model.path_with_namespace, - project_id: model.id, - owner_name: owner.name, - owner_email: owner.respond_to?(:email) ? owner.email : "", - project_visibility: Project.visibility_levels.key(model.visibility_level_field).downcase - }) - when User - data.merge!({ - name: model.name, - email: model.email, - user_id: model.id - }) - when ProjectMember - data.merge!({ - project_name: model.project.name, - project_path: model.project.path, - project_id: model.project.id, - user_name: model.user.name, - user_email: model.user.email, - access_level: model.human_access, - project_visibility: Project.visibility_levels.key(model.project.visibility_level_field).downcase - }) - when Group - owner = model.owner - - data.merge!( - name: model.name, - path: model.path, - group_id: model.id, - owner_name: owner.respond_to?(:name) ? owner.name : nil, - owner_email: owner.respond_to?(:email) ? owner.email : nil, - ) - when GroupMember - data.merge!( - group_name: model.group.name, - group_path: model.group.path, - group_id: model.group.id, - user_name: model.user.name, - user_email: model.user.email, - user_id: model.user.id, - group_access: model.human_access, - ) - end - end - - def build_event_name(model, event) - case model - when ProjectMember - return "user_add_to_team" if event == :create - return "user_remove_from_team" if event == :destroy - when GroupMember - return 'user_add_to_group' if event == :create - return 'user_remove_from_group' if event == :destroy - else - "#{model.class.name.downcase}_#{event.to_s}" - end - end -end diff --git a/app/services/test_hook_service.rb b/app/services/test_hook_service.rb deleted file mode 100644 index 21ec2c01cb86a43c6223a41f95bf87c540a713aa..0000000000000000000000000000000000000000 --- a/app/services/test_hook_service.rb +++ /dev/null @@ -1,6 +0,0 @@ -class TestHookService - def execute(hook, current_user) - data = Gitlab::PushDataBuilder.build_sample(hook.project, current_user) - hook.execute(data) - end -end diff --git a/app/services/update_snippet_service.rb b/app/services/update_snippet_service.rb deleted file mode 100644 index 9d181c2d2aba1d3edaaa84cbe37c129105feea2a..0000000000000000000000000000000000000000 --- a/app/services/update_snippet_service.rb +++ /dev/null @@ -1,22 +0,0 @@ -class UpdateSnippetService < BaseService - attr_accessor :snippet - - def initialize(project, user, snippet, params) - super(project, user, params) - @snippet = snippet - end - - def execute - # check that user is allowed to set specified visibility_level - new_visibility = params[:visibility_level] - if new_visibility && new_visibility.to_i != snippet.visibility_level - unless can?(current_user, :change_visibility_level, snippet) && - Gitlab::VisibilityLevel.allowed_for?(current_user, new_visibility) - deny_visibility_level(snippet, new_visibility) - return snippet - end - end - - snippet.update_attributes(params) - end -end diff --git a/app/uploaders/attachment_uploader.rb b/app/uploaders/attachment_uploader.rb deleted file mode 100644 index a9691bee46e23f20eca66b96e0577b700769b0e1..0000000000000000000000000000000000000000 --- a/app/uploaders/attachment_uploader.rb +++ /dev/null @@ -1,26 +0,0 @@ -# encoding: utf-8 - -class AttachmentUploader < CarrierWave::Uploader::Base - storage :file - - def store_dir - "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" - end - - def image? - img_ext = %w(png jpg jpeg gif bmp tiff) - if file.respond_to?(:extension) - img_ext.include?(file.extension.downcase) - else - # Not all CarrierWave storages respond to :extension - ext = file.path.split('.').last.downcase - img_ext.include?(ext) - end - rescue - false - end - - def file_storage? - self.class.storage == CarrierWave::Storage::File - end -end diff --git a/app/uploaders/avatar_uploader.rb b/app/uploaders/avatar_uploader.rb deleted file mode 100644 index 7cad044555b1aeae2eacba6b7eb57386fdf565b8..0000000000000000000000000000000000000000 --- a/app/uploaders/avatar_uploader.rb +++ /dev/null @@ -1,32 +0,0 @@ -# encoding: utf-8 - -class AvatarUploader < CarrierWave::Uploader::Base - storage :file - - after :store, :reset_events_cache - - def store_dir - "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" - end - - def image? - img_ext = %w(png jpg jpeg gif bmp tiff) - if file.respond_to?(:extension) - img_ext.include?(file.extension.downcase) - else - # Not all CarrierWave storages respond to :extension - ext = file.path.split('.').last.downcase - img_ext.include?(ext) - end - rescue - false - end - - def file_storage? - self.class.storage == CarrierWave::Storage::File - end - - def reset_events_cache(file) - model.reset_events_cache if model.is_a?(User) - end -end diff --git a/app/uploaders/file_uploader.rb b/app/uploaders/file_uploader.rb deleted file mode 100644 index f9673abbfe8a5d0f1ea0d4b6a176c2be373a4128..0000000000000000000000000000000000000000 --- a/app/uploaders/file_uploader.rb +++ /dev/null @@ -1,48 +0,0 @@ -# encoding: utf-8 -class FileUploader < CarrierWave::Uploader::Base - storage :file - - attr_accessor :project, :secret - - def initialize(project, secret = self.class.generate_secret) - @project = project - @secret = secret - end - - def base_dir - "uploads" - end - - def store_dir - File.join(base_dir, @project.path_with_namespace, @secret) - end - - def cache_dir - File.join(base_dir, 'tmp', @project.path_with_namespace, @secret) - end - - def self.generate_secret - SecureRandom.hex - end - - def secure_url - File.join(Gitlab.config.gitlab.url, @project.path_with_namespace, "uploads", @secret, file.filename) - end - - def file_storage? - self.class.storage == CarrierWave::Storage::File - end - - def image? - img_ext = %w(png jpg jpeg gif bmp tiff) - if file.respond_to?(:extension) - img_ext.include?(file.extension.downcase) - else - # Not all CarrierWave storages respond to :extension - ext = file.path.split('.').last.downcase - img_ext.include?(ext) - end - rescue - false - end -end diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml deleted file mode 100644 index 4f3565c67eb8bd5c72fb9b938ee0d05f4fe38fad..0000000000000000000000000000000000000000 --- a/app/views/admin/application_settings/_form.html.haml +++ /dev/null @@ -1,69 +0,0 @@ -= form_for @application_setting, url: admin_application_settings_path, html: { class: 'form-horizontal fieldset-form' } do |f| - - if @application_setting.errors.any? - #error_explanation - .alert.alert-danger - - @application_setting.errors.full_messages.each do |msg| - %p= msg - - %fieldset - %legend Features - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :signup_enabled do - = f.check_box :signup_enabled - Signup enabled - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :signin_enabled do - = f.check_box :signin_enabled - Signin enabled - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :gravatar_enabled do - = f.check_box :gravatar_enabled - Gravatar enabled - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :twitter_sharing_enabled do - = f.check_box :twitter_sharing_enabled, :'aria-describedby' => 'twitter_help_block' - %strong Twitter enabled - %span.help-block#twitter_help_block Show users a button to share their newly created public or internal projects on twitter - %fieldset - %legend Misc - .form-group - = f.label :default_projects_limit, class: 'control-label col-sm-2' - .col-sm-10 - = f.number_field :default_projects_limit, class: 'form-control' - .form-group - = f.label :default_branch_protection, class: 'control-label col-sm-2' - .col-sm-10 - = f.select :default_branch_protection, options_for_select(Gitlab::Access.protection_options, @application_setting.default_branch_protection), {}, class: 'form-control' - .form-group - = f.label :restricted_visibility_levels, class: 'control-label col-sm-2' - .col-sm-10 - - data_attrs = { toggle: 'buttons' } - .btn-group{ data: data_attrs } - - restricted_level_checkboxes('restricted-visibility-help').each do |level| - = level - %span.help-block#restricted-visibility-help Selected levels cannot be used by non-admin users for projects or snippets - .form-group - = f.label :home_page_url, class: 'control-label col-sm-2' - .col-sm-10 - = f.text_field :home_page_url, class: 'form-control', placeholder: 'http://company.example.com', :'aria-describedby' => 'home_help_block' - %span.help-block#home_help_block We will redirect non-logged in users to this page - .form-group - = f.label :sign_in_text, class: 'control-label col-sm-2' - .col-sm-10 - = f.text_area :sign_in_text, class: 'form-control', rows: 4 - .help-block Markdown enabled - .form-group - = f.label :max_attachment_size, 'Maximum attachment size (MB)', class: 'control-label col-sm-2' - .col-sm-10 - = f.number_field :max_attachment_size, class: 'form-control' - - .form-actions - = f.submit 'Save', class: 'btn btn-primary' diff --git a/app/views/admin/application_settings/show.html.haml b/app/views/admin/application_settings/show.html.haml deleted file mode 100644 index 39b66647a5a878754f9afc1ac642ab387d9c91db..0000000000000000000000000000000000000000 --- a/app/views/admin/application_settings/show.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%h3.page-title Application settings -%hr -= render 'form' diff --git a/app/views/admin/applications/_delete_form.html.haml b/app/views/admin/applications/_delete_form.html.haml deleted file mode 100644 index 3147cbd659f20a3efec6beee52498e3cd8feb8f3..0000000000000000000000000000000000000000 --- a/app/views/admin/applications/_delete_form.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- submit_btn_css ||= 'btn btn-link btn-remove btn-sm' -= form_tag admin_application_path(application) do - %input{:name => "_method", :type => "hidden", :value => "delete"}/ - = submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css \ No newline at end of file diff --git a/app/views/admin/applications/_form.html.haml b/app/views/admin/applications/_form.html.haml deleted file mode 100644 index fa4e6335c735271e8daaae9287f07038aca9953f..0000000000000000000000000000000000000000 --- a/app/views/admin/applications/_form.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -= form_for [:admin, @application], url: @url, html: {class: 'form-horizontal', role: 'form'} do |f| - - if application.errors.any? - .alert.alert-danger - %button{ type: "button", class: "close", "data-dismiss" => "alert"} × - - application.errors.full_messages.each do |msg| - %p= msg - = content_tag :div, class: 'form-group' do - = f.label :name, class: 'col-sm-2 control-label' - .col-sm-10 - = f.text_field :name, class: 'form-control' - = doorkeeper_errors_for application, :name - = content_tag :div, class: 'form-group' do - = f.label :redirect_uri, class: 'col-sm-2 control-label' - .col-sm-10 - = f.text_area :redirect_uri, class: 'form-control' - = doorkeeper_errors_for application, :redirect_uri - %span.help-block - Use one line per URI - - if Doorkeeper.configuration.native_redirect_uri - %span.help-block - Use - %code= Doorkeeper.configuration.native_redirect_uri - for local tests - .form-actions - = f.submit 'Submit', class: "btn btn-primary wide" - = link_to "Cancel", admin_applications_path, class: "btn btn-default" diff --git a/app/views/admin/applications/edit.html.haml b/app/views/admin/applications/edit.html.haml deleted file mode 100644 index e408ae2f29d0647bae76bf1c039e33ec525ff34a..0000000000000000000000000000000000000000 --- a/app/views/admin/applications/edit.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%h3.page-title Edit application -- @url = admin_application_path(@application) -= render 'form', application: @application \ No newline at end of file diff --git a/app/views/admin/applications/index.html.haml b/app/views/admin/applications/index.html.haml deleted file mode 100644 index d550278710ebeaf8555308eb868cf9e34f83d55b..0000000000000000000000000000000000000000 --- a/app/views/admin/applications/index.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -%h3.page-title - System OAuth applications -%p.light - System OAuth application does not belong to certain user and can be managed only by admins -%hr -%p= link_to 'New Application', new_admin_application_path, class: 'btn btn-success' -%table.table.table-striped - %thead - %tr - %th Name - %th Callback URL - %th Clients - %th - %th - %tbody.oauth-applications - - @applications.each do |application| - %tr{:id => "application_#{application.id}"} - %td= link_to application.name, admin_application_path(application) - %td= application.redirect_uri - %td= application.access_tokens.map(&:resource_owner_id).uniq.count - %td= link_to 'Edit', edit_admin_application_path(application), class: 'btn btn-link' - %td= render 'delete_form', application: application diff --git a/app/views/admin/applications/new.html.haml b/app/views/admin/applications/new.html.haml deleted file mode 100644 index 7c62425f19c94bd3bee5c05d9ed9a944b0a2b1a4..0000000000000000000000000000000000000000 --- a/app/views/admin/applications/new.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%h3.page-title New application -- @url = admin_applications_path -= render 'form', application: @application \ No newline at end of file diff --git a/app/views/admin/applications/show.html.haml b/app/views/admin/applications/show.html.haml deleted file mode 100644 index 2abe390ce13e7b853e11d7c6f28766375dd2c1d6..0000000000000000000000000000000000000000 --- a/app/views/admin/applications/show.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -%h3.page-title - Application: #{@application.name} - - -%table.table - %tr - %td - Application Id - %td - %code#application_id= @application.uid - %tr - %td - Secret: - %td - %code#secret= @application.secret - - %tr - %td - Callback url - %td - - @application.redirect_uri.split.each do |uri| - %div - %span.monospace= uri -.form-actions - = link_to 'Edit', edit_admin_application_path(@application), class: 'btn btn-primary wide pull-left' - = render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger prepend-left-10' diff --git a/app/views/admin/background_jobs/show.html.haml b/app/views/admin/background_jobs/show.html.haml deleted file mode 100644 index 4ef8e878a7f1c419f8c89c641842d4739a46a17e..0000000000000000000000000000000000000000 --- a/app/views/admin/background_jobs/show.html.haml +++ /dev/null @@ -1,44 +0,0 @@ -%h3.page-title Background Jobs -%p.light GitLab uses #{link_to "sidekiq", "http://sidekiq.org/"} library for async job processing - -%hr - -.panel.panel-default - .panel-heading Sidekiq running processes - .panel-body - - if @sidekiq_processes.empty? - %h4.cred - %i.fa.fa-exclamation-triangle - There are no running sidekiq processes. Please restart GitLab - - else - %table.table - %thead - %th USER - %th PID - %th CPU - %th MEM - %th STATE - %th START - %th COMMAND - %tbody - - @sidekiq_processes.each do |process| - - next unless process.match(/(sidekiq \d+\.\d+\.\d+.+$)/) - - data = process.strip.split(' ') - %tr - %td= gitlab_config.user - - 5.times do - %td= data.shift - %td= data.join(' ') - - .clearfix - %p - %i.fa.fa-exclamation-circle - If '[25 of 25 busy]' is shown, restart GitLab with 'sudo service gitlab reload'. - %p - %i.fa.fa-exclamation-circle - If more than one sidekiq process is listed, stop GitLab, kill the remaining sidekiq processes (sudo pkill -u #{gitlab_config.user} -f sidekiq) and restart GitLab. - - - -.panel.panel-default - %iframe{src: sidekiq_path, width: '100%', height: 970, style: "border: none"} diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml deleted file mode 100644 index 7e29311bf42c6f8d7cf8a6f18f362a11af4ef902..0000000000000000000000000000000000000000 --- a/app/views/admin/broadcast_messages/index.html.haml +++ /dev/null @@ -1,59 +0,0 @@ -%h3.page-title - Broadcast Messages -%p.light - Broadcast messages are displayed for every user and can be used to notify users about scheduled maintenance, recent upgrades and more. -.broadcast-message-preview - %i.fa.fa-bullhorn - %span Your message here - -= form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form form-horizontal'} do |f| - -if @broadcast_message.errors.any? - .alert.alert-danger - - @broadcast_message.errors.full_messages.each do |msg| - %p= msg - .form-group - = f.label :message, class: 'control-label' - .col-sm-10 - = f.text_area :message, class: "form-control", rows: 2, required: true - %div - = link_to '#', class: 'js-toggle-colors-link' do - Customize colors - .form-group.js-toggle-colors-container.hide - = f.label :color, "Background Color", class: 'control-label' - .col-sm-10 - = f.color_field :color, value: "#AA33EE", class: "form-control" - .form-group.js-toggle-colors-container.hide - = f.label :font, "Font Color", class: 'control-label' - .col-sm-10 - = f.color_field :font, value: "#224466", class: "form-control" - .form-group - = f.label :starts_at, class: 'control-label' - .col-sm-10.datetime-controls - = f.datetime_select :starts_at - .form-group - = f.label :ends_at, class: 'control-label' - .col-sm-10.datetime-controls - = f.datetime_select :ends_at - .form-actions - = f.submit "Add broadcast message", class: "btn btn-create" - --if @broadcast_messages.any? - %ul.bordered-list.broadcast-messages - - @broadcast_messages.each do |broadcast_message| - %li - .pull-right - - if broadcast_message.starts_at - %strong - #{broadcast_message.starts_at.to_s(:short)} - \... - - if broadcast_message.ends_at - %strong - #{broadcast_message.ends_at.to_s(:short)} -   - = link_to [:admin, broadcast_message], method: :delete, remote: true, class: 'remove-row btn btn-xs' do - %i.fa.fa-times.cred - - .message= broadcast_message.message - - - = paginate @broadcast_messages diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml deleted file mode 100644 index d1c586328a26abf645b9a3b65b1e3f7b43a3f8e8..0000000000000000000000000000000000000000 --- a/app/views/admin/dashboard/index.html.haml +++ /dev/null @@ -1,137 +0,0 @@ -.admin-dashboard - .row - .col-md-4 - %h4 Statistics - %hr - %p - Forks - %span.light.pull-right - = ForkedProjectLink.count - %p - Issues - %span.light.pull-right - = Issue.count - %p - Merge Requests - %span.light.pull-right - = MergeRequest.count - %p - Notes - %span.light.pull-right - = Note.count - %p - Snippets - %span.light.pull-right - = Snippet.count - %p - SSH Keys - %span.light.pull-right - = Key.count - %p - Milestones - %span.light.pull-right - = Milestone.count - %p - Active Users - %span.light.pull-right - = User.active.count - .col-md-4 - %h4 - Features - %hr - %p - Sign up - %span.light.pull-right - = boolean_to_icon signup_enabled? - %p - LDAP - %span.light.pull-right - = boolean_to_icon Gitlab.config.ldap.enabled - %p - Gravatar - %span.light.pull-right - = boolean_to_icon gravatar_enabled? - %p - OmniAuth - %span.light.pull-right - = boolean_to_icon Gitlab.config.omniauth.enabled - .col-md-4 - %h4 Components - %hr - %p - GitLab - %span.pull-right - = Gitlab::VERSION - %p - GitLab Shell - %span.pull-right - = Gitlab::Shell.new.version - %p - GitLab API - %span.pull-right - = API::API::version - %p - Ruby - %span.pull-right - #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} - - %p - Rails - %span.pull-right - #{Rails::VERSION::STRING} - %hr - .row - .col-sm-4 - .light-well - %h4 Projects - .data - = link_to admin_namespaces_projects_path do - %h1= Project.count - %hr - = link_to('New Project', new_project_path, class: "btn btn-new") - .col-sm-4 - .light-well - %h4 Users - .data - = link_to admin_users_path do - %h1= User.count - %hr - = link_to 'New User', new_admin_user_path, class: "btn btn-new" - .col-sm-4 - .light-well - %h4 Groups - .data - = link_to admin_groups_path do - %h1= Group.count - %hr - = link_to 'New Group', new_admin_group_path, class: "btn btn-new" - - .row.prepend-top-10 - .col-md-4 - %h4 Latest projects - %hr - - @projects.each do |project| - %p - = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project], class: 'str-truncated' - %span.light.pull-right - #{time_ago_with_tooltip(project.created_at)} - - .col-md-4 - %h4 Latest users - %hr - - @users.each do |user| - %p - = link_to [:admin, user], class: 'str-truncated' do - = user.name - %span.light.pull-right - #{time_ago_with_tooltip(user.created_at)} - - .col-md-4 - %h4 Latest groups - %hr - - @groups.each do |group| - %p - = link_to [:admin, group], class: 'str-truncated' do - = group.name - %span.light.pull-right - #{time_ago_with_tooltip(group.created_at)} diff --git a/app/views/admin/deploy_keys/index.html.haml b/app/views/admin/deploy_keys/index.html.haml deleted file mode 100644 index 2ae83ab95f7ffe7df832ce3bf3d5a6b7e02964ed..0000000000000000000000000000000000000000 --- a/app/views/admin/deploy_keys/index.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -.panel.panel-default - .panel-heading - Public deploy keys (#{@deploy_keys.count}) - .panel-head-actions - = link_to 'New Deploy Key', new_admin_deploy_key_path, class: "btn btn-new btn-sm" - - if @deploy_keys.any? - %table.table - %thead.panel-heading - %tr - %th Title - %th Fingerprint - %th Added at - %th - %tbody - - @deploy_keys.each do |deploy_key| - %tr - %td - = link_to admin_deploy_key_path(deploy_key) do - %strong= deploy_key.title - %td - %span - (#{deploy_key.fingerprint}) - %td - %span.cgray - added #{time_ago_with_tooltip(deploy_key.created_at)} - %td - = link_to 'Remove', admin_deploy_key_path(deploy_key), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-sm btn-remove delete-key pull-right" diff --git a/app/views/admin/deploy_keys/new.html.haml b/app/views/admin/deploy_keys/new.html.haml deleted file mode 100644 index c00049424c58180927c409f7b7dd7fd1317f5e34..0000000000000000000000000000000000000000 --- a/app/views/admin/deploy_keys/new.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -%h3.page-title New public deploy key -%hr - -%div - = form_for [:admin, @deploy_key], html: { class: 'deploy-key-form form-horizontal' } do |f| - -if @deploy_key.errors.any? - .alert.alert-danger - %ul - - @deploy_key.errors.full_messages.each do |msg| - %li= msg - - .form-group - = f.label :title, class: "control-label" - .col-sm-10= f.text_field :title, class: 'form-control' - .form-group - = f.label :key, class: "control-label" - .col-sm-10 - %p.light - Paste a machine public key here. Read more about how to generate it - = link_to "here", help_page_path("ssh", "README") - = f.text_area :key, class: "form-control thin_area", rows: 5 - - .form-actions - = f.submit 'Create', class: "btn-create btn" - = link_to "Cancel", admin_deploy_keys_path, class: "btn btn-cancel" - diff --git a/app/views/admin/deploy_keys/show.html.haml b/app/views/admin/deploy_keys/show.html.haml deleted file mode 100644 index cfa2adf92eefb0ab6bf5f9bb8951600768a7d8a4..0000000000000000000000000000000000000000 --- a/app/views/admin/deploy_keys/show.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -.row - .col-md-4 - .panel.panel-default - .panel-heading - Deploy Key - %ul.well-list - %li - %span.light Title: - %strong= @deploy_key.title - %li - %span.light Created on: - %strong= @deploy_key.created_at.stamp("Aug 21, 2011") - - .panel.panel-default - .panel-heading Projects (#{@deploy_key.deploy_keys_projects.count}) - - if @deploy_key.deploy_keys_projects.any? - %ul.well-list - - @deploy_key.projects.each do |project| - %li - %span - %strong - = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project] - .pull-right - = link_to disable_namespace_project_deploy_key_path(project.namespace, project, @deploy_key), data: { confirm: "Are you sure?" }, method: :put, class: "btn-xs btn btn-remove", title: 'Remove deploy key from project' do - %i.fa.fa-times.fa-inverse - - .col-md-8 - %p - %span.light Fingerprint: - %strong= @deploy_key.fingerprint - %pre.well-pre - = @deploy_key.key - .pull-right - = link_to 'Remove', admin_deploy_key_path(@deploy_key), data: {confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove delete-key" diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml deleted file mode 100644 index 9e7751830a4477d972ae68484a8d8466d076c3ae..0000000000000000000000000000000000000000 --- a/app/views/admin/groups/_form.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -= form_for [:admin, @group], html: { class: "form-horizontal" } do |f| - - if @group.errors.any? - .alert.alert-danger - %span= @group.errors.full_messages.first - - = render 'shared/group_form', f: f - - .form-group.group-description-holder - = f.label :avatar, "Group avatar", class: 'control-label' - .col-sm-10 - = render 'shared/choose_group_avatar_button', f: f - - - if @group.new_record? - .form-group - .col-sm-2 - .col-sm-10 - .alert.alert-info - = render 'shared/group_tips' - .form-actions - = f.submit 'Create group', class: "btn btn-create" - = link_to 'Cancel', admin_groups_path, class: "btn btn-cancel" - - - else - .form-actions - = f.submit 'Save changes', class: "btn btn-primary" - = link_to 'Cancel', admin_group_path(@group), class: "btn btn-cancel" - diff --git a/app/views/admin/groups/edit.html.haml b/app/views/admin/groups/edit.html.haml deleted file mode 100644 index 824e51c1cf1340ca4ab2244ea376600257ff4f83..0000000000000000000000000000000000000000 --- a/app/views/admin/groups/edit.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%h3.page-title Edit group: #{@group.name} -%hr -= render 'form' diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml deleted file mode 100644 index 4c53ff55708790a7d5e5a9e47df5c3fe91086668..0000000000000000000000000000000000000000 --- a/app/views/admin/groups/index.html.haml +++ /dev/null @@ -1,62 +0,0 @@ -%h3.page-title - Groups (#{@groups.total_count}) - = link_to 'New Group', new_admin_group_path, class: "btn btn-new pull-right" - -%p.light - Group allows you to keep projects organized. - Use groups for uniting related projects. - -%hr -= form_tag admin_groups_path, method: :get, class: 'form-inline' do - = hidden_field_tag :sort, @sort - .form-group - = text_field_tag :name, params[:name], class: "form-control input-mn-300" - = button_tag "Search", class: "btn submit btn-primary" - - .pull-right - .dropdown.inline - %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %span.light sort: - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_recently_created - %b.caret - %ul.dropdown-menu - %li - = link_to admin_groups_path(sort: sort_value_recently_created) do - = sort_title_recently_created - = link_to admin_groups_path(sort: sort_value_oldest_created) do - = sort_title_oldest_created - = link_to admin_groups_path(sort: sort_value_recently_updated) do - = sort_title_recently_updated - = link_to admin_groups_path(sort: sort_value_oldest_updated) do - = sort_title_oldest_updated - -%hr - -%ul.bordered-list - - @groups.each do |group| - %li - .clearfix - .pull-right.prepend-top-10 - = link_to 'Edit', edit_admin_group_path(group), id: "edit_#{dom_id(group)}", class: "btn btn-sm" - = link_to 'Destroy', [:admin, group], data: {confirm: "REMOVE #{group.name}? Are you sure?"}, method: :delete, class: "btn btn-sm btn-remove" - - %h4 - = link_to [:admin, group] do - %i.fa.fa-folder - = group.name - - → - %span.monospace - %strong #{group.path}/ - .clearfix - %p - = truncate group.description, length: 150 - .clearfix - %p.light - #{pluralize(group.members.size, 'member')}, #{pluralize(group.projects.count, 'project')} - - -= paginate @groups, theme: "gitlab" diff --git a/app/views/admin/groups/new.html.haml b/app/views/admin/groups/new.html.haml deleted file mode 100644 index f46f45c5514853c563a4515d52bbda61ba975a41..0000000000000000000000000000000000000000 --- a/app/views/admin/groups/new.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%h3.page-title New group -%hr -= render 'form' diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml deleted file mode 100644 index 14996dcd6a245a684e45b2fb6fa7c062e19c528f..0000000000000000000000000000000000000000 --- a/app/views/admin/groups/show.html.haml +++ /dev/null @@ -1,91 +0,0 @@ -%h3.page-title - Group: #{@group.name} - - = link_to edit_admin_group_path(@group), class: "btn pull-right" do - %i.fa.fa-pencil-square-o - Edit -%hr -.row - .col-md-6 - .panel.panel-default - .panel-heading - Group info: - %ul.well-list - %li - = image_tag group_icon(@group), class: "avatar s60" - %li - %span.light Name: - %strong= @group.name - %li - %span.light Path: - %strong - = @group.path - - %li - %span.light Description: - %strong - = @group.description - - %li - %span.light Created on: - %strong - = @group.created_at.stamp("March 1, 1999") - - .panel.panel-default - .panel-heading - %h3.panel-title - Projects - %span.badge - #{@group.projects.count} - %ul.well-list - - @projects.each do |project| - %li - %strong - = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project] - %span.label.label-gray - = repository_size(project) - %span.pull-right.light - %span.monospace= project.path_with_namespace + ".git" - .panel-footer - = paginate @projects, param_name: 'projects_page', theme: 'gitlab' - - .col-md-6 - .panel.panel-default - .panel-heading - Add user(s) to the group: - .panel-body.form-holder - %p.light - Read more about project permissions - %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" - - = form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do - %div - = users_select_tag(:user_ids, multiple: true, email_user: true) - %div.prepend-top-10 - = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2" - %hr - = button_tag 'Add users to group', class: "btn btn-create" - .panel.panel-default - .panel-heading - %h3.panel-title - Members - %span.badge - #{@group.group_members.count} - %ul.well-list.group-users-list - - @members.each do |member| - - user = member.user - %li{class: dom_class(member), id: (dom_id(user) if user)} - .list-item-name - - if user - %strong - = link_to user.name, admin_user_path(user) - - else - %strong - = member.invite_email - (invited) - %span.pull-right.light - = member.human_access - = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do - %i.fa.fa-minus.fa-inverse - .panel-footer - = paginate @members, param_name: 'members_page', theme: 'gitlab' diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml deleted file mode 100644 index 7a9dc113f2a93df806c6aa1d3c6b28c69020f8e1..0000000000000000000000000000000000000000 --- a/app/views/admin/hooks/index.html.haml +++ /dev/null @@ -1,37 +0,0 @@ -%h3.page-title - System hooks - -%p.light - #{link_to "System hooks ", help_page_path("system_hooks", "system_hooks"), class: "vlink"} can be - used for binding events when GitLab creates a User or Project. - -%hr - - -= form_for @hook, as: :hook, url: admin_hooks_path, html: { class: 'form-horizontal' } do |f| - -if @hook.errors.any? - .alert.alert-danger - - @hook.errors.full_messages.each do |msg| - %p= msg - .form-group - = f.label :url, "URL:", class: 'control-label' - .col-sm-10 - = f.text_field :url, class: "form-control" - .form-actions - = f.submit "Add System Hook", class: "btn btn-create" -%hr - --if @hooks.any? - .panel.panel-default - .panel-heading - System hooks (#{@hooks.count}) - %ul.well-list - - @hooks.each do |hook| - %li - .list-item-name - = link_to admin_hook_path(hook) do - %strong= hook.url - - .pull-right - = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm" - = link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-remove btn-sm" diff --git a/app/views/admin/keys/show.html.haml b/app/views/admin/keys/show.html.haml deleted file mode 100644 index 5b23027b3abdbee6c68b0589bf846054c37a5b5e..0000000000000000000000000000000000000000 --- a/app/views/admin/keys/show.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "profiles/keys/key_details", admin: true diff --git a/app/views/admin/logs/show.html.haml b/app/views/admin/logs/show.html.haml deleted file mode 100644 index 384c6ee9af5e4fe063a5b32d23946d809fec79c1..0000000000000000000000000000000000000000 --- a/app/views/admin/logs/show.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -- loggers = [Gitlab::GitLogger, Gitlab::AppLogger, - Gitlab::ProductionLogger, Gitlab::SidekiqLogger] -%ul.nav.nav-tabs.log-tabs - - loggers.each do |klass| - %li{ class: (klass == Gitlab::GitLogger ? 'active' : '') } - = link_to klass::file_name, "##{klass::file_name_noext}", - 'data-toggle' => 'tab' -%p.light To prevent performance issues admin logs output the last 2000 lines -.tab-content - - loggers.each do |klass| - .tab-pane{ class: (klass == Gitlab::GitLogger ? 'active' : ''), - id: klass::file_name_noext } - .file-holder#README - .file-title - %i.fa.fa-file - = klass::file_name - .pull-right - = link_to '#', class: 'log-bottom' do - %i.fa.fa-arrow-down - Scroll down - .file-content.logs - %ol - - klass.read_latest.each do |line| - %li - %p= line diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml deleted file mode 100644 index 3bbe10bc270ca0ef8977b835a94f96d6172f0df8..0000000000000000000000000000000000000000 --- a/app/views/admin/projects/index.html.haml +++ /dev/null @@ -1,81 +0,0 @@ -.row - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left - %aside.col-md-3 - .admin-filter - = form_tag admin_namespaces_projects_path, method: :get, class: '' do - .form-group - = label_tag :name, 'Name:' - = text_field_tag :name, params[:name], class: "form-control" - - .form-group - = label_tag :namespace_id, "Namespace" - = namespace_select_tag :namespace_id, selected: params[:namespace_id], class: 'input-large' - - .form-group - %strong Activity - .checkbox - = label_tag :with_push do - = check_box_tag :with_push, 1, params[:with_push] - %span Projects with push events - .checkbox - = label_tag :abandoned do - = check_box_tag :abandoned, 1, params[:abandoned] - %span No activity over 6 month - - %fieldset - %strong Visibility level: - .visibility-levels - - Project.visibility_levels.each do |label, level| - .checkbox - %label - = check_box_tag 'visibility_levels[]', level, params[:visibility_levels].present? && params[:visibility_levels].include?(level.to_s) - %span.descr - = visibility_level_icon(level) - = label - %hr - = hidden_field_tag :sort, params[:sort] - = button_tag "Search", class: "btn submit btn-primary" - = link_to "Reset", admin_namespaces_projects_path, class: "btn btn-cancel" - - %section.col-md-9 - .panel.panel-default - .panel-heading - Projects (#{@projects.total_count}) - .panel-head-actions - .dropdown.inline - %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} - %span.light sort: - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_recently_created - %b.caret - %ul.dropdown-menu - %li - = link_to admin_namespaces_projects_path(sort: sort_value_recently_created) do - = sort_title_recently_created - = link_to admin_namespaces_projects_path(sort: sort_value_oldest_created) do - = sort_title_oldest_created - = link_to admin_namespaces_projects_path(sort: sort_value_recently_updated) do - = sort_title_recently_updated - = link_to admin_namespaces_projects_path(sort: sort_value_oldest_updated) do - = sort_title_oldest_updated - = link_to admin_namespaces_projects_path(sort: sort_value_largest_repo) do - = sort_title_largest_repo - = link_to 'New Project', new_project_path, class: "btn btn-sm btn-success" - %ul.well-list - - @projects.each do |project| - %li - .list-item-name - %span{ class: visibility_level_color(project.visibility_level) } - = visibility_level_icon(project.visibility_level) - = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project] - .pull-right - %span.label.label-gray - = repository_size(project) - = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" - = link_to 'Destroy', [project.namespace.becomes(Namespace), project], data: { confirm: remove_project_message(project) }, method: :delete, class: "btn btn-sm btn-remove" - - if @projects.blank? - .nothing-here-block 0 projects matches - = paginate @projects, theme: "gitlab" diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml deleted file mode 100644 index 78684c692c7e1468b5dc85c81622e2fc9ce8b7ed..0000000000000000000000000000000000000000 --- a/app/views/admin/projects/show.html.haml +++ /dev/null @@ -1,142 +0,0 @@ -%h3.page-title - Project: #{@project.name_with_namespace} - = link_to edit_project_path(@project), class: "btn pull-right" do - %i.fa.fa-pencil-square-o - Edit -%hr -.row - .col-md-6 - .panel.panel-default - .panel-heading - Project info: - %ul.well-list - %li - %span.light Name: - %strong - = link_to @project.name, project_path(@project) - %li - %span.light Namespace: - %strong - - if @project.namespace - = link_to @project.namespace.human_name, [:admin, @project.group || @project.owner] - - else - Global - %li - %span.light Owned by: - %strong - - if @project.owner - = link_to @project.owner_name, [:admin, @project.owner] - - else - (deleted) - - %li - %span.light Created by: - %strong - = @project.creator.try(:name) || '(deleted)' - - %li - %span.light Created on: - %strong - = @project.created_at.stamp("March 1, 1999") - - %li - %span.light http: - %strong - = link_to @project.http_url_to_repo, project_path(@project) - %li - %span.light ssh: - %strong - = link_to @project.ssh_url_to_repo, project_path(@project) - - if @project.repository.exists? - %li - %span.light fs: - %strong - = @repository.path_to_repo - - %li - %span.light Size - %strong - = repository_size(@project) - - %li - %span.light last commit: - %strong - = last_commit(@project) - - else - %li - %span.light repository: - %strong.cred - does not exist - - - if @project.archived? - %li - %span.light archived: - %strong repository is read-only - - %li - %span.light access: - %strong - %span{ class: visibility_level_color(@project.visibility_level) } - = visibility_level_icon(@project.visibility_level) - = visibility_level_label(@project.visibility_level) - - .panel.panel-default - .panel-heading - Transfer project - .panel-body - = form_for @project, url: transfer_admin_namespace_project_path(@project.namespace, @project), method: :put, html: { class: 'form-horizontal' } do |f| - .form-group - = f.label :new_namespace_id, "Namespace", class: 'control-label' - .col-sm-10 - = namespace_select_tag :new_namespace_id, selected: params[:namespace_id], class: 'input-large' - - .form-group - .col-sm-2 - .col-sm-10 - = f.submit 'Transfer', class: 'btn btn-primary' - - .col-md-6 - - if @group - .panel.panel-default - .panel-heading - %strong #{@group.name} - group members (#{@group.group_members.count}) - .pull-right - = link_to admin_group_path(@group), class: 'btn btn-xs' do - %i.fa.fa-pencil-square-o - %ul.well-list - - @group_members.each do |member| - = render 'groups/group_members/group_member', member: member, show_controls: false - .panel-footer - = paginate @group_members, param_name: 'group_members_page', theme: 'gitlab' - - .panel.panel-default - .panel-heading - Project members - %small - (#{@project.users.count}) - .pull-right - = link_to namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-xs" do - %i.fa.fa-pencil-square-o - Manage Access - %ul.well-list.project_members - - @project_members.each do |project_member| - - user = project_member.user - %li.project_member - .list-item-name - - if user - %strong - = link_to user.name, admin_user_path(user) - - else - %strong - = project_member.invite_email - (invited) - .pull-right - - if project_member.owner? - %span.light Owner - - else - %span.light= project_member.human_access - = link_to namespace_project_project_member_path(@project.namespace, @project, project_member), data: { confirm: remove_from_project_team_message(@project, project_member)}, method: :delete, remote: true, class: "btn btn-sm btn-remove" do - %i.fa.fa-times - .panel-footer - = paginate @project_members, param_name: 'project_members_page', theme: 'gitlab' diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml deleted file mode 100644 index eb7a099bfe266dd46051dbdc7a44d36a9a29dc42..0000000000000000000000000000000000000000 --- a/app/views/admin/services/_form.html.haml +++ /dev/null @@ -1,94 +0,0 @@ -%h3.page-title - = @service.title - -%p #{@service.description} template - -= form_for :service, url: admin_application_settings_service_path, method: :put, html: { class: 'form-horizontal fieldset-form' } do |f| - - if @service.errors.any? - #error_explanation - .alert.alert-danger - - @service.errors.full_messages.each do |msg| - %p= msg - - if @service.help.present? - .well - = preserve do - = markdown @service.help - - .form-group - = f.label :active, "Active", class: "control-label" - .col-sm-10 - = f.check_box :active - - - if @service.supported_events.length > 1 - .form-group - = f.label :url, "Trigger", class: 'control-label' - .col-sm-10 - - if @service.supported_events.include?("push") - %div - = f.check_box :push_events, class: 'pull-left' - .prepend-left-20 - = f.label :push_events, class: 'list-label' do - %strong Push events - %p.light - This url will be triggered by a push to the repository - - if @service.supported_events.include?("tag_push") - %div - = f.check_box :tag_push_events, class: 'pull-left' - .prepend-left-20 - = f.label :tag_push_events, class: 'list-label' do - %strong Tag push events - %p.light - This url will be triggered when a new tag is pushed to the repository - - if @service.supported_events.include?("note") - %div - = f.check_box :note_events, class: 'pull-left' - .prepend-left-20 - = f.label :note_events, class: 'list-label' do - %strong Comments - %p.light - This url will be triggered when someone adds a comment - - if @service.supported_events.include?("issue") - %div - = f.check_box :issues_events, class: 'pull-left' - .prepend-left-20 - = f.label :issues_events, class: 'list-label' do - %strong Issues events - %p.light - This url will be triggered when an issue is created - - if @service.supported_events.include?("merge_request") - %div - = f.check_box :merge_requests_events, class: 'pull-left' - .prepend-left-20 - = f.label :merge_requests_events, class: 'list-label' do - %strong Merge Request events - %p.light - This url will be triggered when a merge request is created - - - @service.fields.each do |field| - - name = field[:name] - - title = field[:title] || name.humanize - - value = @service.send(name) unless field[:type] == 'password' - - type = field[:type] - - placeholder = field[:placeholder] - - choices = field[:choices] - - default_choice = field[:default_choice] - - help = field[:help] - - .form-group - = f.label name, title, class: "control-label" - .col-sm-10 - - if type == 'text' - = f.text_field name, class: "form-control", placeholder: placeholder - - elsif type == 'textarea' - = f.text_area name, rows: 5, class: "form-control", placeholder: placeholder - - elsif type == 'checkbox' - = f.check_box name - - elsif type == 'select' - = f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" } - - elsif type == 'password' - = f.password_field name, class: 'form-control' - - if help - %span.help-block= help - - .form-actions - = f.submit 'Save', class: 'btn btn-save' diff --git a/app/views/admin/services/edit.html.haml b/app/views/admin/services/edit.html.haml deleted file mode 100644 index bcc5832792fea10b70d29a9fb15633f06e001dd0..0000000000000000000000000000000000000000 --- a/app/views/admin/services/edit.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render 'form' diff --git a/app/views/admin/services/index.html.haml b/app/views/admin/services/index.html.haml deleted file mode 100644 index 0093fb97765b7aa30666f1540a3c8ff74688eb4f..0000000000000000000000000000000000000000 --- a/app/views/admin/services/index.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -%h3.page-title Service templates -%p.light Service template allows you to set default values for project services - -%table.table - %thead - %tr - %th - %th Service - %th Description - %th Last edit - - @services.sort_by(&:title).each do |service| - %tr - %td - = icon("copy", class: 'clgray') - %td - = link_to edit_admin_application_settings_service_path(service.id) do - %strong= service.title - %td - = service.description - %td.light - = time_ago_in_words service.updated_at - ago diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml deleted file mode 100644 index e18dd9bc905d455a9d1b1af91d5990306806302b..0000000000000000000000000000000000000000 --- a/app/views/admin/users/_form.html.haml +++ /dev/null @@ -1,90 +0,0 @@ -.user_new - = form_for [:admin, @user], html: { class: 'form-horizontal fieldset-form' } do |f| - -if @user.errors.any? - #error_explanation - .alert.alert-danger - - @user.errors.full_messages.each do |msg| - %p= msg - - %fieldset - %legend Account - .form-group - = f.label :name, class: 'control-label' - .col-sm-10 - = f.text_field :name, required: true, autocomplete: "off", class: 'form-control' - %span.help-inline * required - .form-group - = f.label :username, class: 'control-label' - .col-sm-10 - = f.text_field :username, required: true, autocomplete: "off", class: 'form-control' - %span.help-inline * required - .form-group - = f.label :email, class: 'control-label' - .col-sm-10 - = f.text_field :email, required: true, autocomplete: "off", class: 'form-control' - %span.help-inline * required - - - if @user.new_record? - %fieldset - %legend Password - .form-group - = f.label :password, class: 'control-label' - .col-sm-10 - %strong - Reset link will be generated and sent to the user. - %br - User will be forced to set the password on first sign in. - - else - %fieldset - %legend Password - .form-group - = f.label :password, class: 'control-label' - .col-sm-10= f.password_field :password, disabled: f.object.force_random_password, class: 'form-control' - .form-group - = f.label :password_confirmation, class: 'control-label' - .col-sm-10= f.password_field :password_confirmation, disabled: f.object.force_random_password, class: 'form-control' - - %fieldset - %legend Access - .form-group - = f.label :projects_limit, class: 'control-label' - .col-sm-10= f.number_field :projects_limit, class: 'form-control' - - .form-group - = f.label :can_create_group, class: 'control-label' - .col-sm-10= f.check_box :can_create_group - - .form-group - = f.label :admin, class: 'control-label' - - if current_user == @user - .col-sm-10= f.check_box :admin, disabled: true - .col-sm-10 You cannot remove your own admin rights - - else - .col-sm-10= f.check_box :admin - %fieldset - %legend Profile - .form-group - = f.label :avatar, class: 'control-label' - .col-sm-10 - = f.file_field :avatar - - .form-group - = f.label :skype, class: 'control-label' - .col-sm-10= f.text_field :skype, class: 'form-control' - .form-group - = f.label :linkedin, class: 'control-label' - .col-sm-10= f.text_field :linkedin, class: 'form-control' - .form-group - = f.label :twitter, class: 'control-label' - .col-sm-10= f.text_field :twitter, class: 'form-control' - .form-group - = f.label :website_url, 'Website', class: 'control-label' - .col-sm-10= f.text_field :website_url, class: 'form-control' - - .form-actions - - if @user.new_record? - = f.submit 'Create user', class: "btn btn-create" - = link_to 'Cancel', admin_users_path, class: "btn btn-cancel" - - else - = f.submit 'Save changes', class: "btn btn-save" - = link_to 'Cancel', admin_user_path(@user), class: "btn btn-cancel" diff --git a/app/views/admin/users/edit.html.haml b/app/views/admin/users/edit.html.haml deleted file mode 100644 index d71d8189c51274626eb34781fc8ecc462964f0a7..0000000000000000000000000000000000000000 --- a/app/views/admin/users/edit.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%h3.page-title - Edit user: #{@user.name} -.back-link - = link_to admin_user_path(@user) do - ← Back to user page -%hr -= render 'form' diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml deleted file mode 100644 index 25c1730ef70ef93259aef634e0a8ca9582756505..0000000000000000000000000000000000000000 --- a/app/views/admin/users/index.html.haml +++ /dev/null @@ -1,88 +0,0 @@ -.row - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left - %aside.col-md-3 - .admin-filter - %ul.nav.nav-pills.nav-stacked - %li{class: "#{'active' unless params[:filter]}"} - = link_to admin_users_path do - Active - %small.pull-right= User.active.count - %li{class: "#{'active' if params[:filter] == "admins"}"} - = link_to admin_users_path(filter: "admins") do - Admins - %small.pull-right= User.admins.count - %li{class: "#{'active' if params[:filter] == "blocked"}"} - = link_to admin_users_path(filter: "blocked") do - Blocked - %small.pull-right= User.blocked.count - %li{class: "#{'active' if params[:filter] == "wop"}"} - = link_to admin_users_path(filter: "wop") do - Without projects - %small.pull-right= User.without_projects.count - %hr - = form_tag admin_users_path, method: :get, class: 'form-inline' do - .form-group - = search_field_tag :name, params[:name], placeholder: 'Name, email or username', class: 'form-control' - = button_tag class: 'btn btn-primary' do - %i.fa.fa-search - %hr - = link_to 'Reset', admin_users_path, class: "btn btn-cancel" - - %section.col-md-9 - .panel.panel-default - .panel-heading - Users (#{@users.total_count}) - .panel-head-actions - .dropdown.inline - %a.dropdown-toggle.btn.btn-sm{href: '#', "data-toggle" => "dropdown"} - %span.light sort: - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_name - %b.caret - %ul.dropdown-menu - %li - = link_to admin_users_path(sort: sort_value_name) do - = sort_title_name - = link_to admin_users_path(sort: sort_value_recently_signin) do - = sort_title_recently_signin - = link_to admin_users_path(sort: sort_value_oldest_signin) do - = sort_title_oldest_signin - = link_to admin_users_path(sort: sort_value_recently_created) do - = sort_title_recently_created - = link_to admin_users_path(sort: sort_value_oldest_created) do - = sort_title_oldest_created - = link_to admin_users_path(sort: sort_value_recently_updated) do - = sort_title_recently_updated - = link_to admin_users_path(sort: sort_value_oldest_updated) do - = sort_title_oldest_updated - - = link_to 'New User', new_admin_user_path, class: "btn btn-new btn-sm" - %ul.well-list - - @users.each do |user| - %li - .list-item-name - - if user.blocked? - %i.fa.fa-lock.cred - - else - %i.fa.fa-user.cgreen - = link_to user.name, [:admin, user] - - if user.admin? - %strong.cred (Admin) - - if user == current_user - %span.cred It's you! - .pull-right - %span.light - %i.fa.fa-envelope - = mail_to user.email, user.email, class: 'light' -   - = link_to 'Edit', edit_admin_user_path(user), id: "edit_#{dom_id(user)}", class: "btn btn-sm" - - unless user == current_user - - if user.blocked? - = link_to 'Unblock', unblock_admin_user_path(user), method: :put, class: "btn btn-sm success" - - else - = link_to 'Block', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-sm btn-remove" - = link_to 'Destroy', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! All tickets linked to this user will also be removed! Maybe block the user instead? Are you sure?" }, method: :delete, class: "btn btn-sm btn-remove" - = paginate @users, theme: "gitlab" diff --git a/app/views/admin/users/new.html.haml b/app/views/admin/users/new.html.haml deleted file mode 100644 index 8fbb757f42455c1673a7d25681ee513c07740f62..0000000000000000000000000000000000000000 --- a/app/views/admin/users/new.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h3.page-title - New user -%hr -= render 'form' diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml deleted file mode 100644 index 3524f04c5ed5862b12adffb43dfec1f507a8a9fb..0000000000000000000000000000000000000000 --- a/app/views/admin/users/show.html.haml +++ /dev/null @@ -1,227 +0,0 @@ -%h3.page-title - User: - = @user.name - - if @user.blocked? - %span.cred (Blocked) - - if @user.admin - %span.cred (Admin) - - .pull-right - = link_to edit_admin_user_path(@user), class: "btn btn-grouped" do - %i.fa.fa-pencil-square-o - Edit -%hr -%ul.nav.nav-tabs - %li.active - %a{"data-toggle" => "tab", href: "#account"} Account - %li - %a{"data-toggle" => "tab", href: "#profile"} Profile - %li - %a{"data-toggle" => "tab", href: "#groups"} Groups - %li - %a{"data-toggle" => "tab", href: "#projects"} Projects - %li - %a{"data-toggle" => "tab", href: "#ssh-keys"} SSH keys - -.tab-content - #account.tab-pane.active - .row - .col-md-6 - .panel.panel-default - .panel-heading - Account: - %ul.well-list - %li - %span.light Name: - %strong= @user.name - %li - %span.light Username: - %strong - = @user.username - %li - %span.light Email: - %strong - = mail_to @user.email - - @user.emails.each do |email| - %li - %span.light Secondary email: - %strong= email.email - = link_to remove_email_admin_user_path(@user, email), data: { confirm: "Are you sure you want to remove #{email.email}?" }, method: :delete, class: "btn-xs btn btn-remove pull-right", title: 'Remove secondary email', id: "remove_email_#{email.id}" do - %i.fa.fa-times - - %li - %span.light Can create groups: - %strong - = @user.can_create_group ? "Yes" : "No" - %li - %span.light Personal projects limit: - %strong - = @user.projects_limit - %li - %span.light Member since: - %strong - = @user.created_at.stamp("Nov 12, 2031") - - if @user.confirmed_at - %li - %span.light Confirmed at: - %strong - = @user.confirmed_at.stamp("Nov 12, 2031") - - else - %li - %span.light Confirmed: - %strong.cred - No - - %li - %span.light Current sign-in at: - %strong - - if @user.current_sign_in_at - = @user.current_sign_in_at.stamp("Nov 12, 2031") - - else - never - - %li - %span.light Last sign-in at: - %strong - - if @user.last_sign_in_at - = @user.last_sign_in_at.stamp("Nov 12, 2031") - - else - never - - %li - %span.light Sign-in count: - %strong - = @user.sign_in_count - - - if @user.ldap_user? - %li - %span.light LDAP uid: - %strong - = @user.ldap_identity.extern_uid - - - if @user.created_by - %li - %span.light Created by: - %strong - = link_to @user.created_by.name, [:admin, @user.created_by] - - .col-md-6 - - unless @user == current_user - - if @user.blocked? - .panel.panel-info - .panel-heading - This user is blocked - .panel-body - %p Blocking user has the following effects: - %ul - %li User will not be able to login - %li User will not be able to access git repositories - %li Personal projects will be left - %li Owned groups will be left - %br - = link_to 'Unblock user', unblock_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?' } - - else - .panel.panel-warning - .panel-heading - Block this user - .panel-body - %p Blocking user has the following effects: - %ul - %li User will not be able to login - %li User will not be able to access git repositories - %li User will be removed from joined projects and groups - %li Personal projects will be left - %li Owned groups will be left - %br - = link_to 'Block user', block_admin_user_path(@user), data: { confirm: 'USER WILL BE BLOCKED! Are you sure?' }, method: :put, class: "btn btn-warning" - - .panel.panel-danger - .panel-heading - Remove user - .panel-body - %p Deleting a user has the following effects: - %ul - %li All user content like authored issues, snippets, comments will be removed - - rp = @user.personal_projects.count - - unless rp.zero? - %li #{pluralize rp, 'personal project'} will be removed and cannot be restored - - if @user.solo_owned_groups.present? - %li - Next groups with all content will be removed: - %strong #{@user.solo_owned_groups.map(&:name).join(', ')} - %br - = link_to 'Remove user', [:admin, @user], data: { confirm: "USER #{@user.name} WILL BE REMOVED! Are you sure?" }, method: :delete, class: "btn btn-remove" - - #profile.tab-pane - .row - .col-md-6 - .panel.panel-default - .panel-heading - = @user.name - %ul.well-list - %li - = image_tag avatar_icon(@user.email, 60), class: "avatar s60" - %li - %span.light Profile page: - %strong - = link_to user_path(@user) do - = @user.username - .col-md-6 - = render 'users/profile', user: @user - - #groups.tab-pane - - if @user.group_members.present? - .panel.panel-default - .panel-heading Groups: - %ul.well-list - - @user.group_members.each do |group_member| - - group = group_member.group - %li.group_member - %span{class: ("list-item-name" unless group_member.owner?)} - %strong= link_to group.name, admin_group_path(group) - .pull-right - %span.light= group_member.human_access - - unless group_member.owner? - = link_to group_group_member_path(group, group_member), data: { confirm: remove_user_from_group_message(group, group_member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do - %i.fa.fa-times.fa-inverse - - else - .nothing-here-block This user has no groups. - - #projects.tab-pane - - if @user.groups.any? - .panel.panel-default - .panel-heading Group projects - %ul.well-list - - @user.groups.each do |group| - %li - %strong= group.name - – access to - #{pluralize(group.projects.count, 'project')} - - .row - .col-md-6 - = render 'users/projects', projects: @personal_projects - - .col-md-6 - .panel.panel-default - .panel-heading Joined projects (#{@joined_projects.count}) - %ul.well-list - - @joined_projects.sort_by(&:name_with_namespace).each do |project| - - member = project.team.find_member(@user.id) - %li.project_member - .list-item-name - = link_to admin_namespace_project_path(project.namespace, project), class: dom_class(project) do - = project.name_with_namespace - - - if member - .pull-right - - if member.owner? - %span.light Owner - - else - %span.light= member.human_access - - - if member.respond_to? :project - = link_to namespace_project_project_member_path(project.namespace, project, member), data: { confirm: remove_from_project_team_message(project, member) }, remote: true, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from project' do - %i.fa.fa-times - #ssh-keys.tab-pane - = render 'profiles/keys/key_table', admin: true diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml deleted file mode 100644 index c1fc1602d0a2a4bea19efffb85df499d9836c229..0000000000000000000000000000000000000000 --- a/app/views/dashboard/_activities.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -= render "events/event_last_push", event: @last_push -= render 'shared/event_filter' -.content_list -= spinner diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/_projects.html.haml deleted file mode 100644 index d676576067cf0c486aaf925dc36bd847e013463f..0000000000000000000000000000000000000000 --- a/app/views/dashboard/_projects.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -.panel.panel-default - .panel-heading.clearfix - .input-group - = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' - - if current_user.can_create_project? - %span.input-group-btn - = link_to new_project_path, class: 'btn btn-success' do - New project - - = render 'shared/projects_list', projects: @projects, projects_limit: 20 diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml deleted file mode 100644 index 78f695be9160396b2f12a3517ff0cb1e207f6ee3..0000000000000000000000000000000000000000 --- a/app/views/dashboard/_sidebar.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -= render "dashboard/projects", projects: @projects -.prepend-top-20 - = render 'shared/promo' diff --git a/app/views/dashboard/_zero_authorized_projects.html.haml b/app/views/dashboard/_zero_authorized_projects.html.haml deleted file mode 100644 index 4e7d66397276efd4090e82acea5fa1944d35ec57..0000000000000000000000000000000000000000 --- a/app/views/dashboard/_zero_authorized_projects.html.haml +++ /dev/null @@ -1,53 +0,0 @@ -- publicish_project_count = Project.publicish(current_user).count -%h3.page-title Welcome to GitLab! -%p.light Self hosted Git management application. -%hr -%div - .dashboard-intro-icon - %i.fa.fa-bookmark-o - .dashboard-intro-text - %p.slead - You don't have access to any projects right now. - %br - - if current_user.can_create_project? - You can create up to - %strong= pluralize(current_user.projects_limit, "project") + "." - - else - If you are added to a project, it will be displayed here. - - - if current_user.can_create_project? - .link_holder - = link_to new_project_path, class: "btn btn-new" do - %i.fa.fa-plus - New Project - -- if current_user.can_create_group? - %hr - %div - .dashboard-intro-icon - %i.fa.fa-users - .dashboard-intro-text - %p.slead - You can create a group for several dependent projects. - %br - Groups are the best way to manage projects and members. - .link_holder - = link_to new_group_path, class: "btn btn-new" do - %i.fa.fa-plus - New Group - --if publicish_project_count > 0 - %hr - %div - .dashboard-intro-icon - %i.fa.fa-globe - .dashboard-intro-text - %p.slead - There are - %strong= publicish_project_count - public projects on this server. - %br - Public projects are an easy way to allow everyone to have read-only access. - .link_holder - = link_to trending_explore_projects_path, class: "btn btn-new" do - Browse public projects diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml deleted file mode 100644 index 0cb7f764fab43acc98833a0a3e5381ef3ad9a4ad..0000000000000000000000000000000000000000 --- a/app/views/dashboard/groups/index.html.haml +++ /dev/null @@ -1,40 +0,0 @@ -%h3.page-title - Group Membership - - if current_user.can_create_group? - %span.pull-right - = link_to new_group_path, class: "btn btn-new" do - %i.fa.fa-plus - New Group -%p.light - Group members have access to all group projects. -%hr -.panel.panel-default - .panel-heading - %strong Groups - (#{@group_members.count}) - %ul.well-list - - @group_members.each do |group_member| - - group = group_member.group - %li - .pull-right - - if can?(current_user, :admin_group, group) - = link_to edit_group_path(group), class: "btn-sm btn btn-grouped" do - %i.fa.fa-cogs - Settings - - - if can?(current_user, :destroy_group_member, group_member) - = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Remove user from group' do - %i.fa.fa-sign-out - Leave - - = image_tag group_icon(group), class: "avatar s40 avatar-tile" - = link_to group, class: 'group-name' do - %strong= group.name - - as - %strong #{group_member.human_access} - - %div.light - #{pluralize(group.projects.count, "project")}, #{pluralize(group.users.count, "user")} - -= paginate @group_members diff --git a/app/views/dashboard/issues.atom.builder b/app/views/dashboard/issues.atom.builder deleted file mode 100644 index 72e9e361dc3d4f984b8cae48ff87e34baddf4650..0000000000000000000000000000000000000000 --- a/app/views/dashboard/issues.atom.builder +++ /dev/null @@ -1,13 +0,0 @@ -xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do - xml.title "#{current_user.name} issues" - xml.link href: issues_dashboard_url(:atom, private_token: current_user.private_token), rel: "self", type: "application/atom+xml" - xml.link href: issues_dashboard_url(private_token: current_user.private_token), rel: "alternate", type: "text/html" - xml.id issues_dashboard_url(private_token: current_user.private_token) - xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? - - @issues.each do |issue| - issue_to_atom(xml, issue) - end -end - diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml deleted file mode 100644 index db19a46cb263dd075e79dbcd6dc1e62e4396d5a7..0000000000000000000000000000000000000000 --- a/app/views/dashboard/issues.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%h3.page-title - Issues - -%p.light - List all issues from all projects you have access to. -%hr - -.append-bottom-20 - = render 'shared/issuable_filter' -= render 'shared/issues' diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml deleted file mode 100644 index 97a42461b4e0f54d32a91c139bf1ac3818f1f46b..0000000000000000000000000000000000000000 --- a/app/views/dashboard/merge_requests.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%h3.page-title - Merge Requests - - -%p.light - List all merge requests from all projects you have access to. -%hr -.append-bottom-20 - = render 'shared/issuable_filter' -= render 'shared/merge_requests' diff --git a/app/views/dashboard/milestones/_issue.html.haml b/app/views/dashboard/milestones/_issue.html.haml deleted file mode 100644 index f689b9698eb76806e1f50a6fdaa1e1eb9e9058bd..0000000000000000000000000000000000000000 --- a/app/views/dashboard/milestones/_issue.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(issue, 'sortable'), class: 'issue-row', 'data-iid' => issue.iid } - %span.milestone-row - - project = issue.project - %strong #{project.name_with_namespace} · - = link_to [project.namespace.becomes(Namespace), project, issue] do - %span.cgray ##{issue.iid} - = link_to_gfm issue.title, [project.namespace.becomes(Namespace), project, issue], title: issue.title - .pull-right.assignee-icon - - if issue.assignee - = image_tag avatar_icon(issue.assignee.email, 16), class: "avatar s16" diff --git a/app/views/dashboard/milestones/_issues.html.haml b/app/views/dashboard/milestones/_issues.html.haml deleted file mode 100644 index 9f350b772bd90e324398e5981d32510384dc83d9..0000000000000000000000000000000000000000 --- a/app/views/dashboard/milestones/_issues.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list issues-sortable-list" } - - if issues - - issues.each do |issue| - = render 'issue', issue: issue diff --git a/app/views/dashboard/milestones/_merge_request.html.haml b/app/views/dashboard/milestones/_merge_request.html.haml deleted file mode 100644 index 8f5c4cce529b601421a4cb813422e6b86cb99a87..0000000000000000000000000000000000000000 --- a/app/views/dashboard/milestones/_merge_request.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(merge_request, 'sortable'), class: 'mr-row', 'data-iid' => merge_request.iid } - %span.milestone-row - - project = merge_request.project - %strong #{project.name_with_namespace} · - = link_to [project.namespace.becomes(Namespace), project, merge_request] do - %span.cgray ##{merge_request.iid} - = link_to_gfm merge_request.title, [project.namespace.becomes(Namespace), project, merge_request], title: merge_request.title - .pull-right.assignee-icon - - if merge_request.assignee - = image_tag avatar_icon(merge_request.assignee.email, 16), class: "avatar s16" diff --git a/app/views/dashboard/milestones/_merge_requests.html.haml b/app/views/dashboard/milestones/_merge_requests.html.haml deleted file mode 100644 index 50057e2c636db5cb19c5dbf8184ed9a9d5547432..0000000000000000000000000000000000000000 --- a/app/views/dashboard/milestones/_merge_requests.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list merge_requests-sortable-list" } - - if merge_requests - - merge_requests.each do |merge_request| - = render 'merge_request', merge_request: merge_request diff --git a/app/views/dashboard/milestones/_milestone.html.haml b/app/views/dashboard/milestones/_milestone.html.haml deleted file mode 100644 index 21e730bb7ff771e177b50e1325a8ee5ce1dd6abe..0000000000000000000000000000000000000000 --- a/app/views/dashboard/milestones/_milestone.html.haml +++ /dev/null @@ -1,20 +0,0 @@ -%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } - %h4 - = link_to_gfm truncate(milestone.title, length: 100), dashboard_milestone_path(milestone.safe_title, title: milestone.title) - .row - .col-sm-6 - = link_to dashboard_milestone_path(milestone.safe_title, title: milestone.title) do - = pluralize milestone.issue_count, 'Issue' -   - = link_to dashboard_milestone_path(milestone.safe_title, title: milestone.title) do - = pluralize milestone.merge_requests_count, 'Merge Request' -   - %span.light #{milestone.percent_complete}% complete - - .col-sm-6 - = milestone_progress_bar(milestone) - %div - - milestone.milestones.each do |milestone| - = link_to milestone_path(milestone) do - %span.label.label-gray - = milestone.project.name_with_namespace diff --git a/app/views/dashboard/milestones/index.html.haml b/app/views/dashboard/milestones/index.html.haml deleted file mode 100644 index 9944c0df8152abe335797699479d9e1175b3e9bf..0000000000000000000000000000000000000000 --- a/app/views/dashboard/milestones/index.html.haml +++ /dev/null @@ -1,20 +0,0 @@ -%h3.page-title - Milestones - %span.pull-right #{@dashboard_milestones.count} milestones - -%p.light - List all milestones from all projects you have access to. - -%hr - -= render 'shared/milestones_filter' -.milestones - .panel.panel-default - %ul.well-list - - if @dashboard_milestones.blank? - %li - .nothing-here-block No milestones to show - - else - - @dashboard_milestones.each do |milestone| - = render 'milestone', milestone: milestone - = paginate @dashboard_milestones, theme: "gitlab" diff --git a/app/views/dashboard/milestones/show.html.haml b/app/views/dashboard/milestones/show.html.haml deleted file mode 100644 index 57cce9ab749ec85fe3e65118a0864c01311c4b72..0000000000000000000000000000000000000000 --- a/app/views/dashboard/milestones/show.html.haml +++ /dev/null @@ -1,81 +0,0 @@ -%h4.page-title - .issue-box{ class: "issue-box-#{@dashboard_milestone.closed? ? 'closed' : 'open'}" } - - if @dashboard_milestone.closed? - Closed - - else - Open - Milestone #{@dashboard_milestone.title} - -%hr -- if (@dashboard_milestone.total_items_count == @dashboard_milestone.closed_items_count) && @dashboard_milestone.active? - .alert.alert-success - %span All issues for this milestone are closed. You may close the milestone now. - -.description -%table.table - %thead - %tr - %th Project - %th Open issues - %th State - %th Due date - - @dashboard_milestone.milestones.each do |milestone| - %tr - %td - = link_to "#{milestone.project.name_with_namespace}", namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - %td - = milestone.issues.opened.count - %td - - if milestone.closed? - Closed - - else - Open - %td - = milestone.expires_at - -.context - %p.lead - Progress: - #{@dashboard_milestone.closed_items_count} closed - – - #{@dashboard_milestone.open_items_count} open - = milestone_progress_bar(@dashboard_milestone) - -%ul.nav.nav-tabs - %li.active - = link_to '#tab-issues', 'data-toggle' => 'tab' do - Issues - %span.badge= @dashboard_milestone.issue_count - %li - = link_to '#tab-merge-requests', 'data-toggle' => 'tab' do - Merge Requests - %span.badge= @dashboard_milestone.merge_requests_count - %li - = link_to '#tab-participants', 'data-toggle' => 'tab' do - Participants - %span.badge= @dashboard_milestone.participants.count - -.tab-content - .tab-pane.active#tab-issues - .row - .col-md-6 - = render 'issues', title: "Open", issues: @dashboard_milestone.opened_issues - .col-md-6 - = render 'issues', title: "Closed", issues: @dashboard_milestone.closed_issues - - .tab-pane#tab-merge-requests - .row - .col-md-6 - = render 'merge_requests', title: "Open", merge_requests: @dashboard_milestone.opened_merge_requests - .col-md-6 - = render 'merge_requests', title: "Closed", merge_requests: @dashboard_milestone.closed_merge_requests - - .tab-pane#tab-participants - %ul.bordered-list - - @dashboard_milestone.participants.each do |user| - %li - = link_to user, title: user.name, class: "darken" do - = image_tag avatar_icon(user.email, 32), class: "avatar s32" - %strong= truncate(user.name, lenght: 40) - %br - %small.cgray= user.username diff --git a/app/views/dashboard/projects/starred.html.haml b/app/views/dashboard/projects/starred.html.haml deleted file mode 100644 index f4ad2b294b3690f7a799a296cd8255d85ec3d167..0000000000000000000000000000000000000000 --- a/app/views/dashboard/projects/starred.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -- if @projects.any? - .dashboard.row - %section.activities.col-md-8 - = render 'dashboard/activities' - %aside.col-md-4 - .panel.panel-default - .panel-heading.clearfix - .input-group - = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' - - if current_user.can_create_project? - %span.input-group-btn - = link_to new_project_path, class: 'btn btn-success' do - New project - - = render 'shared/projects_list', projects: @projects, - projects_limit: 20, stars: true, avatar: false - - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left - -- else - %h3 You don't have starred projects yet - %p.slead Visit project page and press on star icon and it will appear on this page. diff --git a/app/views/dashboard/show.atom.builder b/app/views/dashboard/show.atom.builder deleted file mode 100644 index da631ecb33e00f01a6f08002da08d78b8f47464c..0000000000000000000000000000000000000000 --- a/app/views/dashboard/show.atom.builder +++ /dev/null @@ -1,12 +0,0 @@ -xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do - xml.title "Dashboard feed#{" - #{current_user.name}" if current_user.name.present?}" - xml.link href: dashboard_url(:atom), rel: "self", type: "application/atom+xml" - xml.link href: dashboard_url, rel: "alternate", type: "text/html" - xml.id projects_url - xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? - - @events.each do |event| - event_to_atom(xml, event) - end -end diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/show.html.haml deleted file mode 100644 index fa8946011b741331df864f866420150af171f20c..0000000000000000000000000000000000000000 --- a/app/views/dashboard/show.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -- if @projects.any? - .dashboard.row - %section.activities.col-md-8 - = render 'activities' - %aside.col-md-4 - = render 'sidebar' - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left - -- else - = render "zero_authorized_projects" diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml deleted file mode 100644 index 970ba1471118bfb89a7e2fa6545ede4a72092531..0000000000000000000000000000000000000000 --- a/app/views/devise/confirmations/new.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -.login-box - .login-heading - %h3 Resend confirmation instructions - .login-body - = form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| - .devise-errors - = devise_error_messages! - .clearfix.append-bottom-20 - = f.email_field :email, placeholder: 'Email', class: "form-control", required: true - .clearfix - = f.submit "Resend confirmation instructions", class: 'btn btn-success' - -.clearfix.prepend-top-20 - = render 'devise/shared/sign_in_link' diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb deleted file mode 100644 index c6fa8f0ee361b4aa7fe07005943820586a46df7d..0000000000000000000000000000000000000000 --- a/app/views/devise/mailer/confirmation_instructions.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -

    Welcome <%= @resource.name %>!

    - -<% if @resource.unconfirmed_email.present? %> -

    You can confirm your email (<%= @resource.unconfirmed_email %>) through the link below:

    -<% else %> -

    You can confirm your account through the link below:

    -<% end %> - -

    <%= link_to 'Confirm your account', confirmation_url(@resource, confirmation_token: @token) %>

    diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb deleted file mode 100644 index 23b31da92d807854ac82c7bab7bc85b4acdacd12..0000000000000000000000000000000000000000 --- a/app/views/devise/mailer/reset_password_instructions.html.erb +++ /dev/null @@ -1,8 +0,0 @@ -

    Hello <%= @resource.email %>!

    - -

    Someone has requested a link to change your password, and you can do this through the link below.

    - -

    <%= link_to 'Change your password', edit_password_url(@resource, reset_password_token: @token) %>

    - -

    If you didn't request this, please ignore this email.

    -

    Your password won't change until you access the link above and create a new one.

    diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb deleted file mode 100644 index 79d6c761d8fce48f4bf9e757392c13cff3ecf16d..0000000000000000000000000000000000000000 --- a/app/views/devise/mailer/unlock_instructions.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -

    Hello <%= @resource.email %>!

    - -

    Your account has been locked due to an excessive amount of unsuccessful sign in attempts.

    - -

    Click the link below to unlock your account:

    - -

    <%= link_to 'Unlock your account', unlock_url(@resource, unlock_token: @token) %>

    diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml deleted file mode 100644 index 56048e99c17f834100138efe080de281fb875821..0000000000000000000000000000000000000000 --- a/app/views/devise/passwords/edit.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -.login-box - .login-heading - %h3 Change your password - .login-body - = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| - .devise-errors - = devise_error_messages! - = f.hidden_field :reset_password_token - %div - = f.password_field :password, class: "form-control top", placeholder: "New password", required: true - %div - = f.password_field :password_confirmation, class: "form-control bottom", placeholder: "Confirm new password", required: true - .clearfix - = f.submit "Change your password", class: "btn btn-primary" - -.clearfix.prepend-top-20 - %p - = link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) - = render 'devise/shared/sign_in_link' diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml deleted file mode 100644 index e8820daf58fe98f28d2bb8bdf6595e4217ae26a6..0000000000000000000000000000000000000000 --- a/app/views/devise/passwords/new.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -.login-box - .login-heading - %h3 Reset password - .login-body - = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| - .devise-errors - = devise_error_messages! - .clearfix.append-bottom-20 - = f.email_field :email, placeholder: "Email", class: "form-control", required: true - .clearfix - = f.submit "Reset password", class: "btn-primary btn" - -.clearfix.prepend-top-20 - = render 'devise/shared/sign_in_link' diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb deleted file mode 100644 index f379e71ae5b444c683b5ee1fd97f69c732f8aa35..0000000000000000000000000000000000000000 --- a/app/views/devise/registrations/edit.html.erb +++ /dev/null @@ -1,28 +0,0 @@ -

    Edit <%= resource_name.to_s.humanize %>

    - -<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> - <%= devise_error_messages! %> - -
    <%= f.label :email %>
    - <%= f.email_field :email %>
    - -
    <%= f.label :name %>
    - <%= f.text_field :name %>
    - -
    <%= f.label :password %> (leave blank if you don't want to change it)
    - <%= f.password_field :password %>
    - -
    <%= f.label :password_confirmation %>
    - <%= f.password_field :password_confirmation %>
    - -
    <%= f.label :current_password %> (we need your current password to confirm your changes)
    - <%= f.password_field :current_password %>
    - -
    <%= f.submit "Update", class: "input_button" %>
    -<% end %> - -

    Cancel your account

    - -

    Unhappy? <%= link_to "Cancel your account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>.

    - -<%= link_to "Back", :back %> diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml deleted file mode 100644 index d3e37f7494c99a4455b05e95bf2aa4804a307dde..0000000000000000000000000000000000000000 --- a/app/views/devise/registrations/new.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -= render 'devise/shared/signup_box' - -= render 'devise/shared/sign_in_link' \ No newline at end of file diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml deleted file mode 100644 index 54a397267714112be0444d0726685a0648b352bc..0000000000000000000000000000000000000000 --- a/app/views/devise/sessions/_new_base.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| - = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus" - = f.password_field :password, class: "form-control bottom", placeholder: "Password" - - if devise_mapping.rememberable? - .remember-me.checkbox - %label{for: "user_remember_me"} - = f.check_box :remember_me - %span Remember me - .pull-right - = link_to "Forgot your password?", new_password_path(resource_name) - %div - = f.submit "Sign in", class: "btn btn-save" diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml deleted file mode 100644 index 812e22373a74b8b3297491ac2937ef0d1eb2d6ed..0000000000000000000000000000000000000000 --- a/app/views/devise/sessions/_new_ldap.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -= form_tag(user_omniauth_callback_path(server['provider_name']), id: 'new_ldap_user' ) do - = text_field_tag :username, nil, {class: "form-control top", placeholder: "#{server['label']} Login", autofocus: "autofocus"} - = password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"} - = button_tag "#{server['label']} Sign in", class: "btn-save btn" diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml deleted file mode 100644 index 89e4e229ac0dd3d1b5c91d65b03f037a23cc79ec..0000000000000000000000000000000000000000 --- a/app/views/devise/sessions/new.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -%div - - if signin_enabled? || ldap_enabled? - = render 'devise/shared/signin_box' - - -# Omniauth fits between signin/ldap signin and signup and does not have a surrounding box - - if Gitlab.config.omniauth.enabled && devise_mapping.omniauthable? - .clearfix.prepend-top-20 - = render 'devise/shared/omniauth_box' - - -# Signup only makes sense if you can also sign-in - - if signin_enabled? && signup_enabled? - .prepend-top-20 - = render 'devise/shared/signup_box' - - -# Show a message if none of the mechanisms above are enabled - - if !signin_enabled? && !ldap_enabled? && !(Gitlab.config.omniauth.enabled && devise_mapping.omniauthable?) - %div - No authentication methods configured. diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb deleted file mode 100644 index 49e99e25c1d27a78895700b76f6bd34e2ce329c3..0000000000000000000000000000000000000000 --- a/app/views/devise/shared/_links.erb +++ /dev/null @@ -1,19 +0,0 @@ -<%- if controller_name != 'sessions' %> - <%= link_to "Sign in", new_session_path(resource_name), class: "btn" %>
    -<% end -%> - -<%- if devise_mapping.registerable? && controller_name != 'registrations' && gitlab_config.signup_enabled %> - <%= link_to "Sign up", new_registration_path(resource_name) %>
    -<% end -%> - -<%- if devise_mapping.recoverable? && controller_name != 'passwords' %> -<%= link_to "Forgot your password?", new_password_path(resource_name), class: "btn" %>
    -<% end -%> - -<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %> - <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
    -<% end -%> - -<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %> - <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
    -<% end -%> diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml deleted file mode 100644 index b647b906b712b27e56b9511f34dbc333e409f5bb..0000000000000000000000000000000000000000 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%p - %span.light - Sign in with   - - providers = additional_providers - - providers.each do |provider| - %span.light - - if default_providers.include?(provider) - = link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), class: 'oauth-image-link' - - else - = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn" diff --git a/app/views/devise/shared/_sign_in_link.html.haml b/app/views/devise/shared/_sign_in_link.html.haml deleted file mode 100644 index fafc4b82f5394cf258ddc2fda1310b153b9a3537..0000000000000000000000000000000000000000 --- a/app/views/devise/shared/_sign_in_link.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%p - %span.light - Already have login and password? - %strong - = link_to "Sign in", new_session_path(resource_name) diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml deleted file mode 100644 index c76574db457d3581a3c73a9599ce902e1572aeee..0000000000000000000000000000000000000000 --- a/app/views/devise/shared/_signin_box.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -.login-box - - if signup_enabled? - .login-heading - %h3 Existing user? Sign in - - else - .login-heading - %h3 Sign in - .login-body - - if ldap_enabled? - %ul.nav.nav-tabs - - @ldap_servers.each_with_index do |server, i| - %li{class: (:active if i.zero?)} - = link_to server['label'], "#tab-#{server['provider_name']}", 'data-toggle' => 'tab' - - if signin_enabled? - %li - = link_to 'Standard', '#tab-signin', 'data-toggle' => 'tab' - .tab-content - - @ldap_servers.each_with_index do |server, i| - %div.tab-pane{id: "tab-#{server['provider_name']}", class: (:active if i.zero?)} - = render 'devise/sessions/new_ldap', server: server - - if signin_enabled? - %div#tab-signin.tab-pane - = render 'devise/sessions/new_base' - - - elsif signin_enabled? - = render 'devise/sessions/new_base' diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml deleted file mode 100644 index 9dc6aeffd5947b903780be359101ab3ae8aa2cb5..0000000000000000000000000000000000000000 --- a/app/views/devise/shared/_signup_box.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -.login-box - - if signin_enabled? - .login-heading - %h3 New user? Create an account - - else - .login-heading - %h3 Create an account - .login-body - = form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| - .devise-errors - = devise_error_messages! - %div - = f.text_field :name, class: "form-control top", placeholder: "Name", required: true - %div - = f.text_field :username, class: "form-control middle", placeholder: "Username", required: true - %div - = f.email_field :email, class: "form-control middle", placeholder: "Email", required: true - .form-group.append-bottom-20#password-strength - = f.password_field :password, class: "form-control bottom", id: "user_password_sign_up", placeholder: "Password", required: true - %div - = f.submit "Sign up", class: "btn-create btn" - -.clearfix.prepend-top-20 - %p - %span.light Didn't receive a confirmation email? - = succeed '.' do - = link_to "Request a new one", new_confirmation_path(resource_name) diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb deleted file mode 100644 index f9277d1673fe35c0ab7a80339cb20c1159871823..0000000000000000000000000000000000000000 --- a/app/views/devise/unlocks/new.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -

    Resend unlock instructions

    - -<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> - <%= devise_error_messages! %> - -
    <%= f.label :email %>
    - <%= f.email_field :email %>
    - -
    <%= f.submit "Resend unlock instructions" %>
    -<% end %> - -<%= render partial: "devise/shared/links" %> diff --git a/app/views/doorkeeper/applications/_delete_form.html.haml b/app/views/doorkeeper/applications/_delete_form.html.haml deleted file mode 100644 index 6a5c917049defbf478f305a9a8aca35c2f5ac420..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/applications/_delete_form.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- submit_btn_css ||= 'btn btn-link btn-remove btn-sm' -= form_tag oauth_application_path(application) do - %input{:name => "_method", :type => "hidden", :value => "delete"}/ - = submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css \ No newline at end of file diff --git a/app/views/doorkeeper/applications/_form.html.haml b/app/views/doorkeeper/applications/_form.html.haml deleted file mode 100644 index a5fec2fabdb400b00c1c3cf02f025e152c37027f..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/applications/_form.html.haml +++ /dev/null @@ -1,24 +0,0 @@ -= form_for application, url: doorkeeper_submit_path(application), html: {class: 'form-horizontal', role: 'form'} do |f| - - if application.errors.any? - .alert.alert-danger{"data-alert" => ""} - %p Whoops! Check your form for possible errors - = content_tag :div, class: "form-group#{' has-error' if application.errors[:name].present?}" do - = f.label :name, class: 'col-sm-2 control-label' - .col-sm-10 - = f.text_field :name, class: 'form-control' - = doorkeeper_errors_for application, :name - = content_tag :div, class: "form-group#{' has-error' if application.errors[:redirect_uri].present?}" do - = f.label :redirect_uri, class: 'col-sm-2 control-label' - .col-sm-10 - = f.text_area :redirect_uri, class: 'form-control' - = doorkeeper_errors_for application, :redirect_uri - %span.help-block - Use one line per URI - - if Doorkeeper.configuration.native_redirect_uri - %span.help-block - Use - %code= Doorkeeper.configuration.native_redirect_uri - for local tests - .form-actions - = f.submit 'Submit', class: "btn btn-primary wide" - = link_to "Cancel", applications_profile_path, class: "btn btn-default" diff --git a/app/views/doorkeeper/applications/edit.html.haml b/app/views/doorkeeper/applications/edit.html.haml deleted file mode 100644 index 61584eb9c498af026e0e0f97767639830a5c3555..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/applications/edit.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%h3.page-title Edit application -= render 'form', application: @application \ No newline at end of file diff --git a/app/views/doorkeeper/applications/index.html.haml b/app/views/doorkeeper/applications/index.html.haml deleted file mode 100644 index e5be4b4bcac03d41252ecc84df4bc7ee5ce6f577..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/applications/index.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -%h3.page-title Your applications -%p= link_to 'New Application', new_oauth_application_path, class: 'btn btn-success' -%table.table.table-striped - %thead - %tr - %th Name - %th Callback URL - %th - %th - %tbody - - @applications.each do |application| - %tr{:id => "application_#{application.id}"} - %td= link_to application.name, oauth_application_path(application) - %td= application.redirect_uri - %td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link' - %td= render 'delete_form', application: application \ No newline at end of file diff --git a/app/views/doorkeeper/applications/new.html.haml b/app/views/doorkeeper/applications/new.html.haml deleted file mode 100644 index 655845e4af55121df2abf04be73e524669f0bfda..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/applications/new.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%h3.page-title New application -= render 'form', application: @application \ No newline at end of file diff --git a/app/views/doorkeeper/applications/show.html.haml b/app/views/doorkeeper/applications/show.html.haml deleted file mode 100644 index 82e78b4af132472bfe0ba411d4e67b25b5781baf..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/applications/show.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -%h3.page-title - Application: #{@application.name} - - -%table.table - %tr - %td - Application Id - %td - %code#application_id= @application.uid - %tr - %td - Secret: - %td - %code#secret= @application.secret - - %tr - %td - Callback url - %td - - @application.redirect_uri.split.each do |uri| - %div - %span.monospace= uri -.form-actions - = link_to 'Edit', edit_oauth_application_path(@application), class: 'btn btn-primary wide pull-left' - = render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger prepend-left-10' diff --git a/app/views/doorkeeper/authorizations/error.html.haml b/app/views/doorkeeper/authorizations/error.html.haml deleted file mode 100644 index 7561ec85ed9563c07b4f2115872892cea55c8c4c..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/authorizations/error.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%h3.page-title An error has occurred -%main{:role => "main"} - %pre= @pre_auth.error_response.body[:error_description] \ No newline at end of file diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml deleted file mode 100644 index 15f9ee266c15a257b806e3997708a42333001df4..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/authorizations/new.html.haml +++ /dev/null @@ -1,28 +0,0 @@ -%h3.page-title Authorize required -%main{:role => "main"} - %p.h4 - Authorize - %strong.text-info= @pre_auth.client.name - to use your account? - - if @pre_auth.scopes - #oauth-permissions - %p This application will be able to: - %ul.text-info - - @pre_auth.scopes.each do |scope| - %li= t scope, scope: [:doorkeeper, :scopes] - %hr/ - .actions - = form_tag oauth_authorization_path, method: :post do - = hidden_field_tag :client_id, @pre_auth.client.uid - = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri - = hidden_field_tag :state, @pre_auth.state - = hidden_field_tag :response_type, @pre_auth.response_type - = hidden_field_tag :scope, @pre_auth.scope - = submit_tag "Authorize", class: "btn btn-success wide pull-left" - = form_tag oauth_authorization_path, method: :delete do - = hidden_field_tag :client_id, @pre_auth.client.uid - = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri - = hidden_field_tag :state, @pre_auth.state - = hidden_field_tag :response_type, @pre_auth.response_type - = hidden_field_tag :scope, @pre_auth.scope - = submit_tag "Deny", class: "btn btn-danger prepend-left-10" \ No newline at end of file diff --git a/app/views/doorkeeper/authorizations/show.html.haml b/app/views/doorkeeper/authorizations/show.html.haml deleted file mode 100644 index 9a402007194b0a898a1088b547cb21f77248ac62..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/authorizations/show.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%h3.page-title Authorization code: -%main{:role => "main"} - %code#authorization_code= params[:code] \ No newline at end of file diff --git a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml deleted file mode 100644 index 4bba72167e3ebc8a0a55721befcfcffa091eec77..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- submit_btn_css ||= 'btn btn-link btn-remove' -= form_tag oauth_authorized_application_path(application) do - %input{:name => "_method", :type => "hidden", :value => "delete"}/ - = submit_tag 'Revoke', onclick: "return confirm('Are you sure?')", class: 'btn btn-link btn-remove btn-sm' \ No newline at end of file diff --git a/app/views/doorkeeper/authorized_applications/index.html.haml b/app/views/doorkeeper/authorized_applications/index.html.haml deleted file mode 100644 index 814cdc987ef7c466f4dbccab541d16be2845947b..0000000000000000000000000000000000000000 --- a/app/views/doorkeeper/authorized_applications/index.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -%header.page-header - %h1 Your authorized applications -%main{:role => "main"} - %table.table.table-striped - %thead - %tr - %th Application - %th Created At - %th - %th - %tbody - - @applications.each do |application| - %tr - %td= application.name - %td= application.created_at.strftime('%Y-%m-%d %H:%M:%S') - %td= render 'delete_form', application: application \ No newline at end of file diff --git a/app/views/errors/access_denied.html.haml b/app/views/errors/access_denied.html.haml deleted file mode 100644 index a1d8664c4ce216ee03702560d9809d58b7e27bb6..0000000000000000000000000000000000000000 --- a/app/views/errors/access_denied.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%h1 403 -%h3 Access Denied -%hr -%p You are not allowed to access this page. -%p Read more about project permissions #{link_to "here", help_page_path("permissions", "permissions"), class: "vlink"} diff --git a/app/views/errors/encoding.html.haml b/app/views/errors/encoding.html.haml deleted file mode 100644 index 64c7451a8dabba140c03f46dd6190760b0f24510..0000000000000000000000000000000000000000 --- a/app/views/errors/encoding.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h1 500 -%h3 Encoding Error -%hr -%p Page can't be loaded because of an encoding error. diff --git a/app/views/errors/git_not_found.html.haml b/app/views/errors/git_not_found.html.haml deleted file mode 100644 index 189e53bca55b7ae44d642591a49d646c63927882..0000000000000000000000000000000000000000 --- a/app/views/errors/git_not_found.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%h1 404 -%h3 Git Resource Not found -%hr -%p - Application can't get access to some branch or commit in your repository. It - may have been moved. diff --git a/app/views/errors/not_found.html.haml b/app/views/errors/not_found.html.haml deleted file mode 100644 index 7bf88f592cf621779b42b1198bdb62354db0a7f1..0000000000000000000000000000000000000000 --- a/app/views/errors/not_found.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h1 404 -%h3 The resource you were looking for doesn't exist. -%hr -%p You may have mistyped the address or the page may have moved. diff --git a/app/views/errors/omniauth_error.html.haml b/app/views/errors/omniauth_error.html.haml deleted file mode 100644 index f3c8221a9d98c970d0415cd2250008c8a08c9682..0000000000000000000000000000000000000000 --- a/app/views/errors/omniauth_error.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -%h1 422 -%h3 Sign-in using #{@provider} auth failed -%hr -%p Sign-in failed because #{@error}. -%p There are couple of steps you can take: - -%ul - %li Try logging in using your email - %li Try logging in using your username - %li If you have forgotten your password, try recovering it using #{ link_to "Password recovery", new_password_path(resource_name) } - -%p If none of the options work, try contacting the GitLab administrator. diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml deleted file mode 100644 index c86ce9ae651ad9f9ceb220a69371ccb1766e6b8b..0000000000000000000000000000000000000000 --- a/app/views/events/_commit.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%li.commit - .commit-row-title - = link_to truncate_sha(commit[:id]), namespace_project_commit_path(project.namespace, project, commit[:id]), class: "commit_short_id", alt: '' -   - = gfm event_commit_title(commit[:message]), project diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml deleted file mode 100644 index 02b1dec753c98b24b347ce2da6c889234cf822f5..0000000000000000000000000000000000000000 --- a/app/views/events/_event.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -- if event.proper? - .event-item{class: "#{event.body? ? "event-block" : "event-inline" }"} - .event-item-timestamp - #{time_ago_with_tooltip(event.created_at)} - - = cache [event, current_user] do - = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:'' - - - if event.push? - = render "events/event/push", event: event - - elsif event.commented? - = render "events/event/note", event: event - - elsif event.created_project? - = render "events/event/created_project", event: event - - else - = render "events/event/common", event: event \ No newline at end of file diff --git a/app/views/events/_event_issue.atom.haml b/app/views/events/_event_issue.atom.haml deleted file mode 100644 index 0edb61ea2467fefc2f5cc5d2c793a781d541dfb0..0000000000000000000000000000000000000000 --- a/app/views/events/_event_issue.atom.haml +++ /dev/null @@ -1,3 +0,0 @@ -%div{xmlns: "http://www.w3.org/1999/xhtml"} - - if issue.description.present? - = markdown(issue.description, xhtml: true) diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml deleted file mode 100644 index d2f0005142abd0599bc46fc1c58dae39177dc3d3..0000000000000000000000000000000000000000 --- a/app/views/events/_event_last_push.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -- if show_last_push_widget?(event) - .event-last-push - .event-last-push-text - %span You pushed to - = link_to namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) do - %strong= event.ref_name - at - %strong= link_to_project event.project - #{time_ago_with_tooltip(event.created_at)} - - .pull-right - = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-create btn-sm" do - Create Merge Request - %hr diff --git a/app/views/events/_event_merge_request.atom.haml b/app/views/events/_event_merge_request.atom.haml deleted file mode 100644 index 1a8b62abeab17fa7eb392fbafc5e541cfc6f1cda..0000000000000000000000000000000000000000 --- a/app/views/events/_event_merge_request.atom.haml +++ /dev/null @@ -1,3 +0,0 @@ -%div{xmlns: "http://www.w3.org/1999/xhtml"} - - if merge_request.description.present? - = markdown(merge_request.description, xhtml: true) diff --git a/app/views/events/_event_note.atom.haml b/app/views/events/_event_note.atom.haml deleted file mode 100644 index b49c331ccf2a7151a20e73d9e39fb27787ddfd83..0000000000000000000000000000000000000000 --- a/app/views/events/_event_note.atom.haml +++ /dev/null @@ -1,2 +0,0 @@ -%div{xmlns: "http://www.w3.org/1999/xhtml"} - = markdown(note.note, xhtml: true) diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml deleted file mode 100644 index 5d14def8f75bd90cd2344f07ad3d32d9f6d34661..0000000000000000000000000000000000000000 --- a/app/views/events/_event_push.atom.haml +++ /dev/null @@ -1,14 +0,0 @@ -%div{xmlns: "http://www.w3.org/1999/xhtml"} - - event.commits.first(15).each do |commit| - %p - %strong= commit[:author][:name] - = link_to "(##{truncate_sha(commit[:id])})", namespace_project_commit_path(event.project.namespace, event.project, id: commit[:id]) - %i - at - = commit[:timestamp].to_time.to_s(:short) - %blockquote= markdown(escape_once(commit[:message]), xhtml: true) - - if event.commits_count > 15 - %p - %i - \... and - = pluralize(event.commits_count - 15, "more commit") diff --git a/app/views/events/_events.html.haml b/app/views/events/_events.html.haml deleted file mode 100644 index 68c19df092da7f0ca114cbf5c958f10ba1d7e3d8..0000000000000000000000000000000000000000 --- a/app/views/events/_events.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render partial: 'events/event', collection: @events diff --git a/app/views/events/event/_common.html.haml b/app/views/events/event/_common.html.haml deleted file mode 100644 index a39e62e9dacc72732f325c415919d7475ea8558d..0000000000000000000000000000000000000000 --- a/app/views/events/event/_common.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -.event-title - %span.author_name= link_to_author event - %span.event_label{class: event.action_name} - = event_action_name(event) - - - if event.target - %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target] - at - - - if event.project - = link_to_project event.project - - else - = event.project_name - -- if event.target.respond_to?(:title) - .event-body - .event-note - = event.target.title diff --git a/app/views/events/event/_created_project.html.haml b/app/views/events/event/_created_project.html.haml deleted file mode 100644 index 552525f4a0783257f881e7dcd125ccdfc986301c..0000000000000000000000000000000000000000 --- a/app/views/events/event/_created_project.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -.event-title - %span.author_name= link_to_author event - %span.event_label{class: event.action_name} - = event_action_name(event) - - - if event.project - = link_to_project event.project - - else - = event.project_name - -- if current_user == event.author && !event.project.private? && twitter_sharing_enabled? - .event-body - .event-note - .md - %p - Congratulations! Why not share your accomplishment with the world? - - %a.twitter-share-button{ | - href: "https://twitter.com/share", | - "data-url" => event.project.web_url, | - "data-text" => "I just #{event.project.imported? ? "imported" : "created"} a new project in GitLab! GitLab is version control on your server.", | - "data-size" => "medium", | - "data-related" => "gitlab", | - "data-hashtags" => "gitlab", | - "data-count" => "none"} - Tweet - %script{src: "//platform.twitter.com/widgets.js"} diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml deleted file mode 100644 index 4ef18c0906018b63829f78bfbb68e73d1ce7fca2..0000000000000000000000000000000000000000 --- a/app/views/events/event/_note.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -.event-title - %span.author_name= link_to_author event - %span.event_label - = event.action_name - = event_note_title_html(event) - at - - - if event.project - = link_to_project event.project - - else - = event.project_name - -.event-body - .event-note - .md - %i.fa.fa-comment-o.event-note-icon - = event_note(event.target.note) - - note = event.target - - if note.attachment.url - - if note.attachment.image? - = link_to note.attachment.url, target: '_blank' do - = image_tag note.attachment.url, class: 'note-image-attach' - - else - = link_to note.attachment.url, target: "_blank", class: 'note-file-attach' do - %i.fa.fa-paperclip - = note.attachment_identifier diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml deleted file mode 100644 index 60d7978b13f07a19b2ee23445335cee072c3f6ec..0000000000000000000000000000000000000000 --- a/app/views/events/event/_push.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -.event-title - %span.author_name= link_to_author event - %span.event_label.pushed #{event.action_name} #{event.ref_type} - - if event.rm_ref? - %strong= event.ref_name - - else - = link_to namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) do - %strong= event.ref_name - at - = link_to_project event.project - -- if event.push_with_commits? - - project = event.project - .event-body - %ul.well-list.event_commits - - few_commits = event.commits[0...2] - - few_commits.each do |commit| - = render "events/commit", commit: commit, project: project - - - if event.commits_count > 1 - %li.commits-stat - - if event.commits_count > 2 - %span ... and #{event.commits_count - 2} more commits. - - if event.md_ref? - - from = event.commit_from - - from_label = truncate_sha(from) - - else - - from = event.project.default_branch - - from_label = from - = link_to namespace_project_compare_path(event.project.namespace, event.project, from: from, to: event.commit_to) do - %strong Compare → #{from_label}...#{truncate_sha(event.commit_to)} diff --git a/app/views/explore/groups/index.html.haml b/app/views/explore/groups/index.html.haml deleted file mode 100644 index 2ea6cb186558187b19d27566ee9143ebe291b419..0000000000000000000000000000000000000000 --- a/app/views/explore/groups/index.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -.clearfix - .pull-left - = form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f| - = hidden_field_tag :sort, @sort - .form-group - = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "groups_search" - .form-group - = button_tag 'Search', class: "btn btn-primary wide" - - .pull-right - .dropdown.inline - %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} - %span.light sort: - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_recently_created - %b.caret - %ul.dropdown-menu - %li - = link_to explore_groups_path(sort: sort_value_recently_created) do - = sort_title_recently_created - = link_to explore_groups_path(sort: sort_value_oldest_created) do - = sort_title_oldest_created - = link_to explore_groups_path(sort: sort_value_recently_updated) do - = sort_title_recently_updated - = link_to explore_groups_path(sort: sort_value_oldest_updated) do - = sort_title_oldest_updated - -%hr - -%ul.bordered-list - - @groups.each do |group| - %li - .clearfix - %h4 - = link_to group_path(id: group.path) do - %i.fa.fa-users - = group.name - .clearfix - %p - = truncate group.description, length: 150 - .clearfix - %p.light - #{pluralize(group.members.size, 'member')}, #{pluralize(group.projects.count, 'project')} - - unless @groups.present? - .nothing-here-block No public groups - - -= paginate @groups, theme: "gitlab" diff --git a/app/views/explore/projects/_filter.html.haml b/app/views/explore/projects/_filter.html.haml deleted file mode 100644 index b3963a9d9013327d4e6a67237993884b0036689c..0000000000000000000000000000000000000000 --- a/app/views/explore/projects/_filter.html.haml +++ /dev/null @@ -1,67 +0,0 @@ -.pull-left - = form_tag explore_projects_filter_path, method: :get, class: 'form-inline form-tiny' do |f| - .form-group - = search_field_tag :search, params[:search], placeholder: "Filter by name", class: "form-control search-text-input input-mn-300", id: "projects_search" - .form-group - = button_tag 'Search', class: "btn btn-primary wide" - -.pull-right.hidden-sm.hidden-xs - - if current_user - .dropdown.inline.append-right-10 - %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %i.fa.fa-globe - %span.light Visibility: - - if params[:visibility_level].present? - = visibility_level_label(params[:visibility_level].to_i) - - else - Any - %b.caret - %ul.dropdown-menu - %li - = link_to explore_projects_filter_path(visibility_level: nil) do - Any - - Gitlab::VisibilityLevel.values.each do |level| - %li{ class: (level.to_s == params[:visibility_level]) ? 'active' : 'light' } - = link_to explore_projects_filter_path(visibility_level: level) do - = visibility_level_icon(level) - = visibility_level_label(level) - - - if @tags.present? - .dropdown.inline.append-right-10 - %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - %i.fa.fa-tags - %span.light Tags: - - if params[:tag].present? - = params[:tag] - - else - Any - %b.caret - %ul.dropdown-menu - %li - = link_to explore_projects_filter_path(tag: nil) do - Any - - - @tags.each do |tag| - %li{ class: (tag.name == params[:tag]) ? 'active' : 'light' } - = link_to explore_projects_filter_path(tag: tag.name) do - %i.fa.fa-tag - = tag.name - - .dropdown.inline - %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} - %span.light sort: - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_recently_created - %b.caret - %ul.dropdown-menu - %li - = link_to explore_projects_filter_path(sort: sort_value_recently_created) do - = sort_title_recently_created - = link_to explore_projects_filter_path(sort: sort_value_oldest_created) do - = sort_title_oldest_created - = link_to explore_projects_filter_path(sort: sort_value_recently_updated) do - = sort_title_recently_updated - = link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do - = sort_title_oldest_updated diff --git a/app/views/explore/projects/_project.html.haml b/app/views/explore/projects/_project.html.haml deleted file mode 100644 index d65fb529373131b7bae68e3f217644124380854b..0000000000000000000000000000000000000000 --- a/app/views/explore/projects/_project.html.haml +++ /dev/null @@ -1,24 +0,0 @@ -%li - %h4.project-title - .project-access-icon - = visibility_level_icon(project.visibility_level) - = link_to project.name_with_namespace, [project.namespace.becomes(Namespace), project] - %span.pull-right - %i.fa.fa-star - = project.star_count - - .project-info - - if project.description.present? - %p.project-description.str-truncated - = project.description - - .repo-info - - unless project.empty_repo? - = link_to pluralize(project.repository.round_commit_count, 'commit'), namespace_project_commits_path(project.namespace, project, project.default_branch) - · - = link_to pluralize(project.repository.branch_names.count, 'branch'), namespace_project_branches_path(project.namespace, project) - · - = link_to pluralize(project.repository.tag_names.count, 'tag'), namespace_project_tags_path(project.namespace, project) - - else - %i.fa.fa-exclamation-triangle - Empty repository diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml deleted file mode 100644 index 5086b58cd03e93e359fb991457a4e0204df4455d..0000000000000000000000000000000000000000 --- a/app/views/explore/projects/index.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -.clearfix - = render 'filter' - -%hr -.public-projects - %ul.bordered-list.top-list - = render @projects - - unless @projects.present? - .nothing-here-block No public projects - - = paginate @projects, theme: "gitlab" diff --git a/app/views/explore/projects/starred.html.haml b/app/views/explore/projects/starred.html.haml deleted file mode 100644 index 420f069375660faba0c25edee18f7de62ec54224..0000000000000000000000000000000000000000 --- a/app/views/explore/projects/starred.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -.explore-trending-block - %p.lead - %i.fa.fa-star - See most starred projects - %hr - .public-projects - %ul.bordered-list - = render @starred_projects - - = paginate @starred_projects, theme: 'gitlab' diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml deleted file mode 100644 index 9cad9238933fc19542d39c340d2c8d55d4122b69..0000000000000000000000000000000000000000 --- a/app/views/explore/projects/trending.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -.explore-trending-block - %p.lead - %i.fa.fa-comments-o - See most discussed projects for last month - %hr - .public-projects - %ul.bordered-list - = render @trending_projects - - .center - = link_to 'Show all projects', explore_projects_path, class: 'btn btn-primary' diff --git a/app/views/groups/_projects.html.haml b/app/views/groups/_projects.html.haml deleted file mode 100644 index 4f8aec1c67e9a4f767febb7cc0f7c5313edef0b9..0000000000000000000000000000000000000000 --- a/app/views/groups/_projects.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -.panel.panel-default - .panel-heading.clearfix - .input-group - = search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control' - - if can? current_user, :create_projects, @group - %span.input-group-btn - = link_to new_project_path(namespace_id: @group.id), class: 'btn btn-success' do - New project - - = render 'shared/projects_list', projects: @projects, projects_limit: 20 diff --git a/app/views/groups/_settings_nav.html.haml b/app/views/groups/_settings_nav.html.haml deleted file mode 100644 index e6aee22e529a1e0afe43511d962dc5b2ca9a2d59..0000000000000000000000000000000000000000 --- a/app/views/groups/_settings_nav.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -%ul.sidebar-subnav - = nav_link(path: 'groups#edit') do - = link_to edit_group_path(@group), title: 'Group' do - %i.fa.fa-pencil-square-o - %span - Group - = nav_link(path: 'groups#projects') do - = link_to projects_group_path(@group), title: 'Projects' do - %i.fa.fa-folder - %span - Projects diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml deleted file mode 100644 index 49e7180bf9873a6d171a77481f04bfc5379f56a9..0000000000000000000000000000000000000000 --- a/app/views/groups/edit.html.haml +++ /dev/null @@ -1,37 +0,0 @@ -.panel.panel-default - .panel-heading - %strong= @group.name - group settings: - .panel-body - = form_for @group, html: { multipart: true, class: "form-horizontal" }, authenticity_token: true do |f| - - if @group.errors.any? - .alert.alert-danger - %span= @group.errors.full_messages.first - = render 'shared/group_form', f: f - - .form-group - .col-sm-2 - .col-sm-10 - = image_tag group_icon(@group), alt: '', class: 'avatar group-avatar s160' - %p.light - - if @group.avatar? - You can change your group avatar here - - else - You can upload a group avatar here - = render 'shared/choose_group_avatar_button', f: f - - if @group.avatar? - %hr - = link_to 'Remove avatar', group_avatar_path(@group.to_param), data: { confirm: "Group avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" - - .form-actions - = f.submit 'Save group', class: "btn btn-save" - -.panel.panel-danger - .panel-heading Remove group - .panel-body - %p - Removing group will cause all child projects and resources to be removed. - %br - %strong Removed group can not be restored! - - = link_to 'Remove Group', @group, data: {confirm: 'Removed group can not be restored! Are you sure?'}, method: :delete, class: "btn btn-remove" diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml deleted file mode 100644 index 56b1948a474cf0ccb44beb1fe916bc2400fb10fb..0000000000000000000000000000000000000000 --- a/app/views/groups/group_members/_group_member.html.haml +++ /dev/null @@ -1,54 +0,0 @@ -- user = member.user -- return unless user || member.invite? -- show_roles = true if show_roles.nil? - -%li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)} - %span{class: ("list-item-name" if show_controls)} - - if member.user - = image_tag avatar_icon(user.email, 16), class: "avatar s16", alt: '' - %strong= user.name - %span.cgray= user.username - - if user == current_user - %span.label.label-success It's you - - if user.blocked? - %label.label.label-danger - %strong Blocked - - else - = image_tag avatar_icon(member.invite_email, 16), class: "avatar s16", alt: '' - %strong - = member.invite_email - %span.cgray - invited - - if member.created_by - by - = link_to member.created_by.name, user_path(member.created_by) - = time_ago_with_tooltip(member.created_at) - - - if show_controls && can?(current_user, :admin_group, @group) - = link_to resend_invite_group_group_member_path(@group, member), method: :post, class: "btn-xs btn", title: 'Resend invite' do - Resend invite - - - if show_roles - %span.pull-right - %strong= member.human_access - - if show_controls - - if can?(current_user, :modify_group_member, member) - = button_tag class: "btn-xs btn js-toggle-button", - title: 'Edit access level', type: 'button' do - %i.fa.fa-pencil-square-o - - if can?(current_user, :destroy_group_member, member) -   - - if current_user == user - = link_to leave_group_group_members_path(@group), data: { confirm: leave_group_message(@group.name)}, method: :delete, class: "btn-xs btn btn-remove", title: 'Remove user from group' do - %i.fa.fa-minus.fa-inverse - - else - = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do - %i.fa.fa-minus.fa-inverse - - .edit-member.hide.js-toggle-content - %br - = form_for [@group, member], remote: true do |f| - .prepend-top-10 - = f.select :access_level, options_for_select(GroupMember.access_level_roles, member.access_level), {}, class: 'form-control' - .prepend-top-10 - = f.submit 'Save', class: 'btn btn-save btn-sm' diff --git a/app/views/groups/group_members/_new_group_member.html.haml b/app/views/groups/group_members/_new_group_member.html.haml deleted file mode 100644 index 3361d7e2a8d279fb6ffaed64de52c00615f74c2d..0000000000000000000000000000000000000000 --- a/app/views/groups/group_members/_new_group_member.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -= form_for @group_member, url: group_group_members_path(@group), html: { class: 'form-horizontal users-group-form' } do |f| - .form-group - = f.label :user_ids, "People", class: 'control-label' - .col-sm-10 - = users_select_tag(:user_ids, multiple: true, class: 'input-large', scope: :all, email_user: true) - .help-block - Search for existing users or invite new ones using their email address. - - .form-group - = f.label :access_level, "Group Access", class: 'control-label' - .col-sm-10 - = select_tag :access_level, options_for_select(GroupMember.access_level_roles, @group_member.access_level), class: "project-access-select select2" - .help-block - Read more about role permissions - %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" - - .form-actions - = f.submit 'Add users to group', class: "btn btn-create" diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml deleted file mode 100644 index c0c9cd170ad6d717747fc8985bd2f27f7e08cc8a..0000000000000000000000000000000000000000 --- a/app/views/groups/group_members/index.html.haml +++ /dev/null @@ -1,43 +0,0 @@ -- show_roles = should_user_see_group_roles?(current_user, @group) - -%h3.page-title - Group members -- if show_roles - %p.light - Members of group have access to all group projects. - Read more about permissions - %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" - -%hr - -.clearfix.js-toggle-container - = form_tag group_group_members_path(@group), method: :get, class: 'form-inline member-search-form' do - .form-group - = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input input-mn-300' } - = button_tag 'Search', class: 'btn' - - - if current_user && current_user.can?(:admin_group, @group) - .pull-right - = button_tag class: 'btn btn-new js-toggle-button', type: 'button' do - Add members - %i.fa.fa-chevron-down - - .js-toggle-content.hide.new-group-member-holder - = render "new_group_member" - -.panel.panel-default.prepend-top-20 - .panel-heading - %strong #{@group.name} - group members - %small - (#{@members.total_count}) - %ul.well-list - - @members.each do |member| - = render 'groups/group_members/group_member', member: member, show_roles: show_roles, show_controls: true - -= paginate @members, theme: 'gitlab' - -:coffeescript - $('form.member-search-form').on 'submit', (event) -> - event.preventDefault() - Turbolinks.visit @.action + '?' + $(@).serialize() diff --git a/app/views/groups/group_members/update.js.haml b/app/views/groups/group_members/update.js.haml deleted file mode 100644 index 5bad48abafd0e908d7dcf6eca0de33c39fefdfc2..0000000000000000000000000000000000000000 --- a/app/views/groups/group_members/update.js.haml +++ /dev/null @@ -1,2 +0,0 @@ -:plain - $("##{dom_id(@member)}").replaceWith('#{escape_javascript(render(@member, member: @member, show_controls: true))}'); diff --git a/app/views/groups/issues.atom.builder b/app/views/groups/issues.atom.builder deleted file mode 100644 index 240001967f36a8e55664e6c7d99da2c95634f2db..0000000000000000000000000000000000000000 --- a/app/views/groups/issues.atom.builder +++ /dev/null @@ -1,13 +0,0 @@ -xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do - xml.title "#{@user.name} issues" - xml.link :href => issues_dashboard_url(:atom, :private_token => @user.private_token), :rel => "self", :type => "application/atom+xml" - xml.link :href => issues_dashboard_url(:private_token => @user.private_token), :rel => "alternate", :type => "text/html" - xml.id issues_dashboard_url(:private_token => @user.private_token) - xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? - - @issues.each do |issue| - issue_to_atom(xml, issue) - end -end - diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml deleted file mode 100644 index 6c0d89c4e7cbf7e67aecb1fd8333a7526c50de86..0000000000000000000000000000000000000000 --- a/app/views/groups/issues.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -%h3.page-title - Issues - -%p.light - Only issues from - %strong #{@group.name} - group are listed here. - - if current_user - To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page. -%hr - -.append-bottom-20 - = render 'shared/issuable_filter' -= render 'shared/issues' diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml deleted file mode 100644 index 1ad74905636f7f3b0637696bcaa6262b36ab4766..0000000000000000000000000000000000000000 --- a/app/views/groups/merge_requests.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%h3.page-title - Merge Requests - -%p.light - Only merge requests from - %strong #{@group.name} - group are listed here. - - if current_user - To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page. -%hr -.append-bottom-20 - = render 'shared/issuable_filter' -= render 'shared/merge_requests' diff --git a/app/views/groups/milestones/_issue.html.haml b/app/views/groups/milestones/_issue.html.haml deleted file mode 100644 index 09f9b4b896906d07db480142df62bbbe6b241174..0000000000000000000000000000000000000000 --- a/app/views/groups/milestones/_issue.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(issue, 'sortable'), class: 'issue-row', 'data-iid' => issue.iid } - %span.milestone-row - - project = issue.project - %strong #{project.name} · - = link_to [project.namespace.becomes(Namespace), project, issue] do - %span.cgray ##{issue.iid} - = link_to_gfm issue.title, [project.namespace.becomes(Namespace), project, issue], title: issue.title - .pull-right.assignee-icon - - if issue.assignee - = image_tag avatar_icon(issue.assignee.email, 16), class: "avatar s16", alt: '' diff --git a/app/views/groups/milestones/_issues.html.haml b/app/views/groups/milestones/_issues.html.haml deleted file mode 100644 index 9f350b772bd90e324398e5981d32510384dc83d9..0000000000000000000000000000000000000000 --- a/app/views/groups/milestones/_issues.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list issues-sortable-list" } - - if issues - - issues.each do |issue| - = render 'issue', issue: issue diff --git a/app/views/groups/milestones/_merge_request.html.haml b/app/views/groups/milestones/_merge_request.html.haml deleted file mode 100644 index d0d1426762b5fb41840f4004bf5b0582150b3a21..0000000000000000000000000000000000000000 --- a/app/views/groups/milestones/_merge_request.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{ id: dom_id(merge_request, 'sortable'), class: 'mr-row', 'data-iid' => merge_request.iid } - %span.milestone-row - - project = merge_request.project - %strong #{project.name} · - = link_to [project.namespace.becomes(Namespace), project, merge_request] do - %span.cgray ##{merge_request.iid} - = link_to_gfm merge_request.title, [project.namespace.becomes(Namespace), project, merge_request], title: merge_request.title - .pull-right.assignee-icon - - if merge_request.assignee - = image_tag avatar_icon(merge_request.assignee.email, 16), class: "avatar s16", alt: '' diff --git a/app/views/groups/milestones/_merge_requests.html.haml b/app/views/groups/milestones/_merge_requests.html.haml deleted file mode 100644 index 50057e2c636db5cb19c5dbf8184ed9a9d5547432..0000000000000000000000000000000000000000 --- a/app/views/groups/milestones/_merge_requests.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list merge_requests-sortable-list" } - - if merge_requests - - merge_requests.each do |merge_request| - = render 'merge_request', merge_request: merge_request diff --git a/app/views/groups/milestones/_milestone.html.haml b/app/views/groups/milestones/_milestone.html.haml deleted file mode 100644 index 30093d2d05d100c36dfa79066c2d41a05a4a31c4..0000000000000000000000000000000000000000 --- a/app/views/groups/milestones/_milestone.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) } - .pull-right - - if can?(current_user, :admin_group, @group) - - if milestone.closed? - = link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen" - - else - = link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-sm btn-close" - %h4 - = link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title) - .row - .col-sm-6 - = link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do - = pluralize milestone.issue_count, 'Issue' -   - = link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do - = pluralize milestone.merge_requests_count, 'Merge Request' -   - %span.light #{milestone.percent_complete}% complete - .col-sm-6 - = milestone_progress_bar(milestone) - %div - - milestone.milestones.each do |milestone| - = link_to milestone_path(milestone) do - %span.label.label-gray - = milestone.project.name diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml deleted file mode 100644 index 008d5a6bd22486a89388d9e5f756255b50428297..0000000000000000000000000000000000000000 --- a/app/views/groups/milestones/index.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -%h3.page-title - Milestones - %span.pull-right #{@group_milestones.count} milestones - -%p.light - Only milestones from - %strong #{@group.name} - group are listed here. - -%hr - -= render 'shared/milestones_filter' -.milestones - .panel.panel-default - %ul.well-list - - if @group_milestones.blank? - %li - .nothing-here-block No milestones to show - - else - - @group_milestones.each do |milestone| - = render 'milestone', milestone: milestone - = paginate @group_milestones, theme: "gitlab" diff --git a/app/views/groups/milestones/show.html.haml b/app/views/groups/milestones/show.html.haml deleted file mode 100644 index fb32f2caa4c8bcb7d5c4523257327280884c7d31..0000000000000000000000000000000000000000 --- a/app/views/groups/milestones/show.html.haml +++ /dev/null @@ -1,87 +0,0 @@ -%h4.page-title - .issue-box{ class: "issue-box-#{@group_milestone.closed? ? 'closed' : 'open'}" } - - if @group_milestone.closed? - Closed - - else - Open - Milestone #{@group_milestone.title} - .pull-right - - if can?(current_user, :admin_group, @group) - - if @group_milestone.active? - = link_to 'Close Milestone', group_milestone_path(@group, @group_milestone.safe_title, title: @group_milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-sm btn-close" - - else - = link_to 'Reopen Milestone', group_milestone_path(@group, @group_milestone.safe_title, title: @group_milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen" - -%hr -- if (@group_milestone.total_items_count == @group_milestone.closed_items_count) && @group_milestone.active? - .alert.alert-success - %span All issues for this milestone are closed. You may close the milestone now. - -.description -%table.table - %thead - %tr - %th Project - %th Open issues - %th State - %th Due date - - @group_milestone.milestones.each do |milestone| - %tr - %td - = link_to "#{milestone.project.name}", namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - %td - = milestone.issues.opened.count - %td - - if milestone.closed? - Closed - - else - Open - %td - = milestone.expires_at - -.context - %p.lead - Progress: - #{@group_milestone.closed_items_count} closed - – - #{@group_milestone.open_items_count} open - = milestone_progress_bar(@group_milestone) - -%ul.nav.nav-tabs - %li.active - = link_to '#tab-issues', 'data-toggle' => 'tab' do - Issues - %span.badge= @group_milestone.issue_count - %li - = link_to '#tab-merge-requests', 'data-toggle' => 'tab' do - Merge Requests - %span.badge= @group_milestone.merge_requests_count - %li - = link_to '#tab-participants', 'data-toggle' => 'tab' do - Participants - %span.badge= @group_milestone.participants.count - -.tab-content - .tab-pane.active#tab-issues - .row - .col-md-6 - = render 'issues', title: "Open", issues: @group_milestone.opened_issues - .col-md-6 - = render 'issues', title: "Closed", issues: @group_milestone.closed_issues - - .tab-pane#tab-merge-requests - .row - .col-md-6 - = render 'merge_requests', title: "Open", merge_requests: @group_milestone.opened_merge_requests - .col-md-6 - = render 'merge_requests', title: "Closed", merge_requests: @group_milestone.closed_merge_requests - - .tab-pane#tab-participants - %ul.bordered-list - - @group_milestone.participants.each do |user| - %li - = link_to user, title: user.name, class: "darken" do - = image_tag avatar_icon(user.email, 32), class: "avatar s32" - %strong= truncate(user.name, lenght: 40) - %br - %small.cgray= user.username diff --git a/app/views/groups/new.html.haml b/app/views/groups/new.html.haml deleted file mode 100644 index 6e17cdaef6f9c9a1870b74c592e2e359b976c607..0000000000000000000000000000000000000000 --- a/app/views/groups/new.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -= form_for @group, html: { class: 'group-form form-horizontal' } do |f| - - if @group.errors.any? - .alert.alert-danger - %span= @group.errors.full_messages.first - - = render 'shared/group_form', f: f, autofocus: true - - .form-group.group-description-holder - = f.label :avatar, "Group avatar", class: 'control-label' - .col-sm-10 - = render 'shared/choose_group_avatar_button', f: f - - .form-group - .col-sm-2 - .col-sm-10 - = render 'shared/group_tips' - - .form-actions - = f.submit 'Create group', class: "btn btn-create", tabindex: 3 diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml deleted file mode 100644 index 0d547984cc9403f459493374020e6660b263849b..0000000000000000000000000000000000000000 --- a/app/views/groups/projects.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -.panel.panel-default - .panel-heading - %strong= @group.name - projects: - - if can? current_user, :admin_group, @group - .panel-head-actions - = link_to new_project_path(namespace_id: @group.id), class: "btn btn-sm btn-success" do - %i.fa.fa-plus - New Project - %ul.well-list - - @projects.each do |project| - %li - .list-item-name - = visibility_level_icon(project.visibility_level) - %strong= link_to project.name_with_namespace, project - %span.label.label-gray - = repository_size(project) - .pull-right - = link_to 'Members', namespace_project_project_members_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" - = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" - = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-sm btn-remove" - - if @projects.blank? - .nothing-here-block This group has no projects yet - -= paginate @projects, theme: "gitlab" diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder deleted file mode 100644 index c78bd1bd2637f2412f6f1f90a346ea86fe495e57..0000000000000000000000000000000000000000 --- a/app/views/groups/show.atom.builder +++ /dev/null @@ -1,12 +0,0 @@ -xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do - xml.title "Group feed - #{@group.name}" - xml.link href: group_path(@group, :atom), rel: "self", type: "application/atom+xml" - xml.link href: group_path(@group), rel: "alternate", type: "text/html" - xml.id projects_url - xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? - - @events.each do |event| - event_to_atom(xml, event) - end -end diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml deleted file mode 100644 index 8df9366ecbe9d9a9e2cc91dd63f08dac2e0a1a5f..0000000000000000000000000000000000000000 --- a/app/views/groups/show.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -.dashboard - .header-with-avatar.clearfix - = image_tag group_icon(@group), class: "avatar group-avatar s90" - %h3 - = @group.name - .username - @#{@group.path} - - if @group.description.present? - .description - = escaped_autolink(@group.description) - %hr - .row - %section.activities.col-md-8 - - if current_user - = render "events/event_last_push", event: @last_push - = render 'shared/event_filter' - .content_list - = spinner - %aside.side.col-md-4 - = render "projects", projects: @projects - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml deleted file mode 100644 index 7b21ca30d8c4d7e7dde99773eda4b27c77ff6c0d..0000000000000000000000000000000000000000 --- a/app/views/help/_shortcuts.html.haml +++ /dev/null @@ -1,209 +0,0 @@ -#modal-shortcuts.modal.hide{tabindex: -1} - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h4 - Keyboard Shortcuts - %small - = link_to '(Show all)', '#', class: 'js-more-help-button' - .modal-body.shortcuts-cheatsheet - .col-lg-4 - %table.shortcut-mappings - %tbody - %tr - %th - %th Global Shortcuts - %tr - %td.shortcut - .key s - %td Focus Search - %tr - %td.shortcut - .key ? - %td Show this dialog - %tbody - %tr - %th - %th Project Files browsing - %tr - %td.shortcut - .key - %i.fa.fa-arrow-up - %td Move selection up - %tr - %td.shortcut - .key - %i.fa.fa-arrow-down - %td Move selection down - %tr - %td.shortcut - .key enter - %td Open Selection - - .col-lg-4 - %table.shortcut-mappings - %tbody{ class: 'hidden-shortcut project', style: 'display:none' } - %tr - %th - %th Global Dashboard - %tr - %td.shortcut - .key g - .key a - %td - Go to the activity feed - %tr - %td.shortcut - .key g - .key p - %td - Go to projects - %tr - %td.shortcut - .key g - .key i - %td - Go to issues - %tr - %td.shortcut - .key g - .key m - %td - Go to merge requests - %tbody - %tr - %th - %th Project - %tr - %td.shortcut - .key g - .key p - %td - Go to the project's activity feed - %tr - %td.shortcut - .key g - .key f - %td - Go to files - %tr - %td.shortcut - .key g - .key c - %td - Go to commits - %tr - %td.shortcut - .key g - .key n - %td - Go to network graph - %tr - %td.shortcut - .key g - .key g - %td - Go to graphs - %tr - %td.shortcut - .key g - .key i - %td - Go to issues - %tr - %td.shortcut - .key g - .key m - %td - Go to merge requests - %tr - %td.shortcut - .key g - .key s - %td - Go to snippets - .col-lg-4 - %table.shortcut-mappings - %tbody{ class: 'hidden-shortcut network', style: 'display:none' } - %tr - %th - %th Network Graph - %tr - %td.shortcut - .key - %i.fa.fa-arrow-left - \/ - .key h - %td Scroll left - %tr - %td.shortcut - .key - %i.fa.fa-arrow-right - \/ - .key l - %td Scroll right - %tr - %td.shortcut - .key - %i.fa.fa-arrow-up - \/ - .key k - %td Scroll up - %tr - %td.shortcut - .key - %i.fa.fa-arrow-down - \/ - .key j - %td Scroll down - %tr - %td.shortcut - .key - shift - %i.fa.fa-arrow-up - \/ - .key - shift k - %td Scroll to top - %tr - %td.shortcut - .key - shift - %i.fa.fa-arrow-down - \/ - .key - shift j - %td Scroll to bottom - %tbody{ class: 'hidden-shortcut issues', style: 'display:none' } - %tr - %th - %th Issues - %tr - %td.shortcut - .key a - %td Change assignee - %tr - %td.shortcut - .key m - %td Change milestone - %tbody{ class: 'hidden-shortcut merge_reuests', style: 'display:none' } - %tr - %th - %th Merge Requests - %tr - %td.shortcut - .key a - %td Change assignee - %tr - %td.shortcut - .key m - %td Change milestone - - -:javascript - $('.js-more-help-button').click(function(e){ - $(this).remove() - $('.hidden-shortcut').show() - e.preventDefault() - }); diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml deleted file mode 100644 index af39dfeac5b5834f5fe7f43feacfdf19a496adf3..0000000000000000000000000000000000000000 --- a/app/views/help/index.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -%div - %h1 - GitLab - %span= Gitlab::VERSION - %small= Gitlab::REVISION - %p.slead - GitLab is open source software to collaborate on code. - %br - Manage git repositories with fine grained access controls that keep your code secure. - %br - Perform code reviews and enhance collaboration with merge requests. - %br - Each project can also have an issue tracker and a wiki. - %br - Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises. - %br - Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank'}. - -%hr - -.row - .col-md-8 - .documentation-index - = preserve do - - readme_text = File.read(Rails.root.join("doc", "README.md")) - - text = readme_text.dup - - readme_text.scan(/\]\(([^(]+)\)/) { |match| text.gsub!(match.first, "help/#{match.first}") } - = markdown text - - .col-md-4 - .panel.panel-default - .panel-heading - Quick help - %ul.well-list - %li - See our website for - = link_to 'getting help', promo_url + '/getting-help/' - %li - Use the - = link_to 'search bar', '#', onclick: 'Shortcuts.focusSearch(event)' - on the top of this page - %li - Use - = link_to 'shortcuts', '#', onclick: 'Shortcuts.showHelp(event)' - %li - Get a support - = link_to 'subscription', 'https://about.gitlab.com/pricing/' - %li - = link_to 'Compare', 'https://about.gitlab.com/features/#compare' - GitLab editions diff --git a/app/views/help/shortcuts.js.haml b/app/views/help/shortcuts.js.haml deleted file mode 100644 index 99ed042ea3b324cffbd4c8f144d1d1d62f4344ba..0000000000000000000000000000000000000000 --- a/app/views/help/shortcuts.js.haml +++ /dev/null @@ -1,3 +0,0 @@ -:plain - $("body").append("#{escape_javascript(render('shortcuts'))}"); - $("#modal-shortcuts").modal(); diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml deleted file mode 100644 index 246a6c1bdfd5dbd46bd4d7f915e9ec9e8a9b1317..0000000000000000000000000000000000000000 --- a/app/views/help/ui.html.haml +++ /dev/null @@ -1,227 +0,0 @@ -- lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fermentum nisi sapien, non consequat lectus aliquam ultrices. Suspendisse sodales est euismod nunc condimentum, a consectetur diam ornare." - -.gitlab-ui-dev-kit - %h1 GitLab UI development kit - %p.light - Use page inspector in your browser to check element classes and structure - of examples below. - %hr - %ul - %li - = link_to 'Blocks', '#blocks' - %li - = link_to 'Lists', '#lists' - %li - = link_to 'Tables', '#tables' - %li - = link_to 'Buttons', '#buttons' - %li - = link_to 'Panels', '#panels' - %li - = link_to 'Alerts', '#alerts' - %li - = link_to 'Forms', '#forms' - %li - = link_to 'Files', '#file' - %li - = link_to 'Markdown', '#markdown' - - %h2#blocks Blocks - - %h3 - %code .well - - - .well - %h4 Something - = lorem - - - %h2#lists Lists - - %h3 - %code .well-list - %ul.well-list - %li - One item - %li - One item - %li - One item - - %h3 - %code .panel .well-list - - .panel.panel-default - .panel-heading Your list - %ul.well-list - %li - One item - %li - One item - %li - One item - - %h3 - %code .bordered-list - %ul.bordered-list - %li - One item - %li - One item - %li - One item - - - - %h2#tables Tables - - .example - %table.table - %thead - %tr - %th # - %th First Name - %th Last Name - %th Username - %tbody - %tr - %td 1 - %td Mark - %td Otto - %td @mdo - %tr - %td 2 - %td Jacob - %td Thornton - %td @fat - %tr - %td 3 - %td Larry - %td the Bird - %td @twitter - - - %h2#buttons Buttons - - .example - %button.btn.btn-default{:type => "button"} Default - %button.btn.btn-primary{:type => "button"} Primary - %button.btn.btn-success{:type => "button"} Success - %button.btn.btn-info{:type => "button"} Info - %button.btn.btn-warning{:type => "button"} Warning - %button.btn.btn-danger{:type => "button"} Danger - %button.btn.btn-link{:type => "button"} Link - - %h2#panels Panels - - .row - .col-md-6 - .panel.panel-success - .panel-heading Success - .panel-body - = lorem - .panel.panel-primary - .panel-heading Primary - .panel-body - = lorem - .panel.panel-info - .panel-heading Info - .panel-body - = lorem - .col-md-6 - .panel.panel-warning - .panel-heading Warning - .panel-body - = lorem - .panel.panel-danger - .panel-heading Danger - .panel-body - = lorem - - %h2#alert Alerts - - .row - .col-md-6 - .alert.alert-success - = lorem - .alert.alert-primary - = lorem - .alert.alert-info - = lorem - .col-md-6 - .alert.alert-warning - = lorem - .alert.alert-danger - = lorem - - %h2#forms Forms - - %h3 - %code form.horizontal-form - - %form.form-horizontal - .form-group - %label.col-sm-2.control-label{:for => "inputEmail3"} Email - .col-sm-10 - %input#inputEmail3.form-control{:placeholder => "Email", :type => "email"}/ - .form-group - %label.col-sm-2.control-label{:for => "inputPassword3"} Password - .col-sm-10 - %input#inputPassword3.form-control{:placeholder => "Password", :type => "password"}/ - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - %label - %input{:type => "checkbox"}/ - Remember me - .form-group - .col-sm-offset-2.col-sm-10 - %button.btn.btn-default{:type => "submit"} Sign in - - %h3 - %code form - - %form - .form-group - %label{:for => "exampleInputEmail1"} Email address - %input#exampleInputEmail1.form-control{:placeholder => "Enter email", :type => "email"}/ - .form-group - %label{:for => "exampleInputPassword1"} Password - %input#exampleInputPassword1.form-control{:placeholder => "Password", :type => "password"}/ - .checkbox - %label - %input{:type => "checkbox"}/ - Remember me - %button.btn.btn-default{:type => "submit"} Sign in - - %h2#file File - %h3 - %code .file-holder - - - blob = Snippet.new(content: "Wow\nSuch\nFile") - .example - .file-holder - .file-title - Awesome file - .file-actions - .btn-group - %a.btn Edit - %a.btn Remove - .file-contenta.code - = render 'shared/file_highlight', blob: blob - - - %h2#markdown Markdown - %h3 - %code .md or .wiki and others - - Markdown rendering has a bit different css and presented in next UI elements: - - %ul - %li comment - %li issue, merge request description - %li wiki page - %li help page - - You can check how markdown rendered at #{link_to 'Markdown help page', help_page_path("markdown", "markdown")}. diff --git a/app/views/import/base/create.js.haml b/app/views/import/base/create.js.haml deleted file mode 100644 index 90a6f5f9d2dc5764716424c3e041db79739ee68b..0000000000000000000000000000000000000000 --- a/app/views/import/base/create.js.haml +++ /dev/null @@ -1,25 +0,0 @@ -- if @already_been_taken - :plain - target_field = $("tr#repo_#{@repo_id} .import-target") - origin_target = target_field.text() - project_name = "#{@project_name}" - origin_namespace = "#{@target_namespace}" - target_field.empty() - target_field.append("

    This namespace already been taken! Please choose another one

    ") - target_field.append("") - target_field.append("/" + project_name) - target_field.data("project_name", project_name) - target_field.find('input').prop("value", origin_namespace) -- elsif @access_denied - :plain - job = $("tr#repo_#{@repo_id}") - job.find(".import-actions").html("

    Access denied! Please verify you can add deploy keys to this repository.

    ") -- else - :plain - job = $("tr#repo_#{@repo_id}") - job.attr("id", "project_#{@project.id}") - target_field = job.find(".import-target") - target_field.empty() - target_field.append('#{link_to @project.path_with_namespace, [@project.namespace.becomes(Namespace), @project]}') - $("table.import-jobs tbody").prepend(job) - job.addClass("active").find(".import-actions").html(" started") diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml deleted file mode 100644 index 4e49bbbc7fa1184bb16fd77049776d82eab15893..0000000000000000000000000000000000000000 --- a/app/views/import/bitbucket/status.html.haml +++ /dev/null @@ -1,45 +0,0 @@ -%h3.page-title - %i.fa.fa-bitbucket - Import projects from Bitbucket - -%p.light - Select projects you want to import. -%hr -%p - = button_tag 'Import all projects', class: "btn btn-success js-import-all" - -%table.table.import-jobs - %thead - %tr - %th From Bitbucket - %th To GitLab - %th Status - %tbody - - @already_added_projects.each do |project| - %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} - %td - = link_to project.import_source, "https://bitbucket.org/#{project.import_source}", target: "_blank" - %td - %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] - %td.job-status - - if project.import_status == 'finished' - %span - %i.fa.fa-check - done - - elsif project.import_status == 'started' - %i.fa.fa-spinner.fa-spin - started - - else - = project.human_import_status_name - - - @repos.each do |repo| - %tr{id: "repo_#{repo["owner"]}___#{repo["slug"]}"} - %td - = link_to "#{repo["owner"]}/#{repo["slug"]}", "https://bitbucket.org/#{repo["owner"]}/#{repo["slug"]}", target: "_blank" - %td.import-target - = "#{repo["owner"]}/#{repo["slug"]}" - %td.import-actions.job-status - = button_tag "Import", class: "btn js-add-to-import" - -:coffeescript - new ImporterStatus("#{jobs_import_bitbucket_path}", "#{import_bitbucket_path}") diff --git a/app/views/import/github/status.html.haml b/app/views/import/github/status.html.haml deleted file mode 100644 index f0bc3e6b1ac91abca4c2510d93712920526381fd..0000000000000000000000000000000000000000 --- a/app/views/import/github/status.html.haml +++ /dev/null @@ -1,45 +0,0 @@ -%h3.page-title - %i.fa.fa-github - Import projects from GitHub - -%p.light - Select projects you want to import. -%hr -%p - = button_tag 'Import all projects', class: "btn btn-success js-import-all" - -%table.table.import-jobs - %thead - %tr - %th From GitHub - %th To GitLab - %th Status - %tbody - - @already_added_projects.each do |project| - %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} - %td - = link_to project.import_source, "https://github.com/#{project.import_source}", target: "_blank" - %td - %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] - %td.job-status - - if project.import_status == 'finished' - %span - %i.fa.fa-check - done - - elsif project.import_status == 'started' - %i.fa.fa-spinner.fa-spin - started - - else - = project.human_import_status_name - - - @repos.each do |repo| - %tr{id: "repo_#{repo.id}"} - %td - = link_to repo.full_name, "https://github.com/#{repo.full_name}", target: "_blank" - %td.import-target - = repo.full_name - %td.import-actions.job-status - = button_tag "Import", class: "btn js-add-to-import" - -:coffeescript - new ImporterStatus("#{jobs_import_github_path}", "#{import_github_path}") diff --git a/app/views/import/gitlab/status.html.haml b/app/views/import/gitlab/status.html.haml deleted file mode 100644 index 33b0a21acf3b187e1c1d996c7fd3f57a6d5463f5..0000000000000000000000000000000000000000 --- a/app/views/import/gitlab/status.html.haml +++ /dev/null @@ -1,45 +0,0 @@ -%h3.page-title - %i.fa.fa-heart - Import projects from GitLab.com - -%p.light - Select projects you want to import. -%hr -%p - = button_tag 'Import all projects', class: "btn btn-success js-import-all" - -%table.table.import-jobs - %thead - %tr - %th From GitLab.com - %th To this GitLab instance - %th Status - %tbody - - @already_added_projects.each do |project| - %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} - %td - = link_to project.import_source, "https://gitlab.com/#{project.import_source}", target: "_blank" - %td - %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] - %td.job-status - - if project.import_status == 'finished' - %span - %i.fa.fa-check - done - - elsif project.import_status == 'started' - %i.fa.fa-spinner.fa-spin - started - - else - = project.human_import_status_name - - - @repos.each do |repo| - %tr{id: "repo_#{repo["id"]}"} - %td - = link_to repo["path_with_namespace"], "https://gitlab.com/#{repo["path_with_namespace"]}", target: "_blank" - %td.import-target - = repo["path_with_namespace"] - %td.import-actions.job-status - = button_tag "Import", class: "btn js-add-to-import" - -:coffeescript - new ImporterStatus("#{jobs_import_gitlab_path}", "#{import_gitlab_path}") diff --git a/app/views/import/gitorious/status.html.haml b/app/views/import/gitorious/status.html.haml deleted file mode 100644 index 78c5e957be0f3d1feb65952da4de5c3a9ad8c487..0000000000000000000000000000000000000000 --- a/app/views/import/gitorious/status.html.haml +++ /dev/null @@ -1,45 +0,0 @@ -%h3.page-title - %i.icon-gitorious.icon-gitorious-big - Import projects from Gitorious.org - -%p.light - Select projects you want to import. -%hr -%p - = button_tag 'Import all projects', class: "btn btn-success js-import-all" - -%table.table.import-jobs - %thead - %tr - %th From Gitorious.org - %th To GitLab - %th Status - %tbody - - @already_added_projects.each do |project| - %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} - %td - = link_to project.import_source, "https://gitorious.org/#{project.import_source}", target: "_blank" - %td - %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] - %td.job-status - - if project.import_status == 'finished' - %span - %i.fa.fa-check - done - - elsif project.import_status == 'started' - %i.fa.fa-spinner.fa-spin - started - - else - = project.human_import_status_name - - - @repos.each do |repo| - %tr{id: "repo_#{repo.id}"} - %td - = link_to repo.full_name, "https://gitorious.org/#{repo.full_name}", target: "_blank" - %td.import-target - = repo.full_name - %td.import-actions.job-status - = button_tag "Import", class: "btn js-add-to-import" - -:coffeescript - new ImporterStatus("#{jobs_import_gitorious_path}", "#{import_gitorious_path}") diff --git a/app/views/import/google_code/new.html.haml b/app/views/import/google_code/new.html.haml deleted file mode 100644 index ce78fec205f1683207e0a21b2e7058a5266d89d2..0000000000000000000000000000000000000000 --- a/app/views/import/google_code/new.html.haml +++ /dev/null @@ -1,60 +0,0 @@ -%h3.page-title - %i.fa.fa-google - Import projects from Google Code -%hr - -= form_tag callback_import_google_code_path, class: 'form-horizontal', multipart: true do - %p - Follow the steps below to export your Google Code project data. - In the next step, you'll be able to select the projects you want to import. - %ol - %li - %p - Go to - #{link_to "Google Takeout", "https://www.google.com/settings/takeout", target: "_blank"}. - %li - %p - Make sure you're logged into the account that owns the projects you'd like to import. - %li - %p - Click the Select none button on the right, since we only need "Google Code Project Hosting". - %li - %p - Scroll down to Google Code Project Hosting and enable the switch on the right. - %li - %p - Choose Next at the bottom of the page. - %li - %p - Leave the "File type" and "Delivery method" options on their default values. - %li - %p - Choose Create archive and wait for archiving to complete. - %li - %p - Click the Download button and wait for downloading to complete. - %li - %p - Find the downloaded ZIP file and decompress it. - %li - %p - Find the newly extracted Takeout/Google Code Project Hosting/GoogleCodeProjectHosting.json file. - %li - %p - Upload GoogleCodeProjectHosting.json here: - %p - %input{type: "file", name: "dump_file", id: "dump_file"} - %li - %p - Do you want to customize how Google Code email addresses and usernames are imported into GitLab? - %p - = label_tag :create_user_map_0 do - = radio_button_tag :create_user_map, 0, true - No, directly import the existing email addresses and usernames. - %p - = label_tag :create_user_map_1 do - = radio_button_tag :create_user_map, 1, false - Yes, let me map Google Code users to full names or GitLab users. - %li - %p - = submit_tag 'Continue to the next step', class: "btn btn-create" diff --git a/app/views/import/google_code/status.html.haml b/app/views/import/google_code/status.html.haml deleted file mode 100644 index 2013b8c03c6e59489e27b6ee11650c89dbcc6b16..0000000000000000000000000000000000000000 --- a/app/views/import/google_code/status.html.haml +++ /dev/null @@ -1,49 +0,0 @@ -%h3.page-title - %i.fa.fa-google - Import projects from Google Code - -%p.light - Select projects you want to import. -%p.light - Optionally, you can - = link_to "customize", new_user_map_import_google_code_path - how Google Code email addresses and usernames are imported into GitLab. -%hr -%p - = button_tag 'Import all projects', class: "btn btn-success js-import-all" - -%table.table.import-jobs - %thead - %tr - %th From Google Code - %th To GitLab - %th Status - %tbody - - @already_added_projects.each do |project| - %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} - %td - = link_to project.import_source, "https://code.google.com/p/#{project.import_source}", target: "_blank" - %td - %strong= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] - %td.job-status - - if project.import_status == 'finished' - %span - %i.fa.fa-check - done - - elsif project.import_status == 'started' - %i.fa.fa-spinner.fa-spin - started - - else - = project.human_import_status_name - - - @repos.each do |repo| - %tr{id: "repo_#{repo.id}"} - %td - = link_to repo.name, "https://code.google.com/p/#{repo.name}", target: "_blank" - %td.import-target - = "#{current_user.username}/#{repo.name}" - %td.import-actions.job-status - = button_tag "Import", class: "btn js-add-to-import" - -:coffeescript - new ImporterStatus("#{jobs_import_google_code_path}", "#{import_google_code_path}") diff --git a/app/views/invites/show.html.haml b/app/views/invites/show.html.haml deleted file mode 100644 index ab0ecffe4d2b24524efc69007cfaa9a5324b7d3a..0000000000000000000000000000000000000000 --- a/app/views/invites/show.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -%h3.page-title Invitation - -%p - You have been invited - - if inviter = @member.created_by - by - = link_to inviter.name, user_url(inviter) - to join - - case @member.source - - when Project - - project = @member.source - project - %strong - = link_to project.name_with_namespace, namespace_project_url(project.namespace, project) - - when Group - - group = @member.source - group - %strong - = link_to group.name, group_url(group) - as #{@member.human_access}. - -- if @member.source.users.include?(current_user) - %p - However, you are already a member of this #{@member.source.is_a?(Group) ? "group" : "project"}. - Sign in using a different account to accept the invitation. -- else - .actions - = link_to "Accept invitation", accept_invite_url(@token), method: :post, class: "btn btn-success" - = link_to "Decline", decline_invite_url(@token), method: :post, class: "btn btn-danger prepend-left-10" diff --git a/app/views/kaminari/gitlab/_first_page.html.haml b/app/views/kaminari/gitlab/_first_page.html.haml deleted file mode 100644 index 41c9c0b3af6dc2beafbe5cc9cb9b779f34726da1..0000000000000000000000000000000000000000 --- a/app/views/kaminari/gitlab/_first_page.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Link to the "First" page --# available local variables --# url: url to the first page --# current_page: a page object for the currently displayed page --# num_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%span.first - = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote diff --git a/app/views/kaminari/gitlab/_gap.html.haml b/app/views/kaminari/gitlab/_gap.html.haml deleted file mode 100644 index 3ffd12f8587aa72b3929dbdcbfbaf999383111b6..0000000000000000000000000000000000000000 --- a/app/views/kaminari/gitlab/_gap.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Non-link tag that stands for skipped pages... --# available local variables --# current_page: a page object for the currently displayed page --# num_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%li{class: "page"} - %span.page.gap - = raw(t 'views.pagination.truncate') diff --git a/app/views/kaminari/gitlab/_last_page.html.haml b/app/views/kaminari/gitlab/_last_page.html.haml deleted file mode 100644 index b03a206224c18a56c2c3cfca78c018a6aab795f4..0000000000000000000000000000000000000000 --- a/app/views/kaminari/gitlab/_last_page.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Link to the "Last" page --# available local variables --# url: url to the last page --# current_page: a page object for the currently displayed page --# num_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%span.last - = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {remote: remote} diff --git a/app/views/kaminari/gitlab/_next_page.html.haml b/app/views/kaminari/gitlab/_next_page.html.haml deleted file mode 100644 index 00c5f0b6f4e3fc9a71c81d2a674fcaac213c856d..0000000000000000000000000000000000000000 --- a/app/views/kaminari/gitlab/_next_page.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Link to the "Next" page --# available local variables --# url: url to the next page --# current_page: a page object for the currently displayed page --# num_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%li.next - = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote diff --git a/app/views/kaminari/gitlab/_page.html.haml b/app/views/kaminari/gitlab/_page.html.haml deleted file mode 100644 index a52d883b9a84611e1f272aaf001b04bfdefdda2d..0000000000000000000000000000000000000000 --- a/app/views/kaminari/gitlab/_page.html.haml +++ /dev/null @@ -1,10 +0,0 @@ --# Link showing page number --# available local variables --# page: a page object for "this" page --# url: url to this page --# current_page: a page object for the currently displayed page --# num_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%li{class: "page#{' active' if page.current?}"} - = link_to page, url, {remote: remote, rel: page.next? ? 'next' : page.prev? ? 'prev' : nil} diff --git a/app/views/kaminari/gitlab/_paginator.html.haml b/app/views/kaminari/gitlab/_paginator.html.haml deleted file mode 100644 index 4f7996e49961cd2468f0a8feb2e134b43c4f602a..0000000000000000000000000000000000000000 --- a/app/views/kaminari/gitlab/_paginator.html.haml +++ /dev/null @@ -1,17 +0,0 @@ --# The container tag --# available local variables --# current_page: a page object for the currently displayed page --# num_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote --# paginator: the paginator that renders the pagination tags inside -= paginator.render do - %div.gl-pagination - %ul.pagination - = prev_page_tag unless current_page.first? - - each_page do |page| - - if page.left_outer? || page.right_outer? || page.inside_window? - = page_tag page - - elsif !page.was_truncated? - = gap_tag - = next_page_tag unless current_page.last? diff --git a/app/views/kaminari/gitlab/_prev_page.html.haml b/app/views/kaminari/gitlab/_prev_page.html.haml deleted file mode 100644 index f673abdb3ae8b6cc9859f1ede9d24a44e431c551..0000000000000000000000000000000000000000 --- a/app/views/kaminari/gitlab/_prev_page.html.haml +++ /dev/null @@ -1,9 +0,0 @@ --# Link to the "Previous" page --# available local variables --# url: url to the previous page --# current_page: a page object for the currently displayed page --# num_pages: total number of pages --# per_page: number of items to fetch per page --# remote: data-remote -%li{class: "prev" } - = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote diff --git a/app/views/layouts/_broadcast.html.haml b/app/views/layouts/_broadcast.html.haml deleted file mode 100644 index e7d477c225eb35e812b6a592510b862f7e949eee..0000000000000000000000000000000000000000 --- a/app/views/layouts/_broadcast.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- if broadcast_message.present? - .broadcast-message{ style: broadcast_styling(broadcast_message) } - %i.fa.fa-bullhorn - = broadcast_message.message diff --git a/app/views/layouts/_collapse_button.html.haml b/app/views/layouts/_collapse_button.html.haml deleted file mode 100644 index 2ed51d87ca1332d8c9d7b34ba3a7219b662a53f9..0000000000000000000000000000000000000000 --- a/app/views/layouts/_collapse_button.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- if nav_menu_collapsed? - = link_to icon('angle-right'), '#', class: 'toggle-nav-collapse', title: "Open/Close" -- else - = link_to icon('angle-left'), '#', class: 'toggle-nav-collapse', title: "Open/Close" diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml deleted file mode 100644 index cc8ea066cb9b98e7b014e625fc0d05fbd803365e..0000000000000000000000000000000000000000 --- a/app/views/layouts/_flash.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -.flash-container - - if alert - .flash-alert - = alert - - - elsif notice - .flash-notice - = notice diff --git a/app/views/layouts/_google_analytics.html.haml b/app/views/layouts/_google_analytics.html.haml deleted file mode 100644 index 81e03c7eff29dd0fdbd5cc945e0099da332dcc46..0000000000000000000000000000000000000000 --- a/app/views/layouts/_google_analytics.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -:javascript - var _gaq = _gaq || []; - _gaq.push(['_setAccount', '#{extra_config.google_analytics_id}']); - _gaq.push(['_trackPageview']); - - (function() { - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); - })(); diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml deleted file mode 100644 index d12145651af0f5f833419a7e20aa63fa0affec46..0000000000000000000000000000000000000000 --- a/app/views/layouts/_head.html.haml +++ /dev/null @@ -1,28 +0,0 @@ -%head - %meta{charset: "utf-8"} - %meta{content: "GitLab Community Edition", name: "description"} - - %title - = "#{title} | " if defined?(title) - GitLab - = favicon_link_tag 'favicon.ico' - = stylesheet_link_tag "application", :media => "all" - = stylesheet_link_tag "print", :media => "print" - = javascript_include_tag "application" - = csrf_meta_tags - = include_gon - %meta{name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=1'} - %meta{name: 'theme-color', content: '#474D57'} - - = render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id') - = render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id') - - -# Atom feed - - if current_user - - if controller_name == 'projects' && action_name == 'index' - = auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard feed" - - if @project && !@project.new_record? - - if current_controller?(:tree, :commits) - = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}") - - if current_controller?(:issues) - = auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues") diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml deleted file mode 100644 index d58582c107a0e31307164313fdd9e9da74bf7fbf..0000000000000000000000000000000000000000 --- a/app/views/layouts/_head_panel.html.haml +++ /dev/null @@ -1,48 +0,0 @@ -%header.navbar.navbar-fixed-top.navbar-gitlab - .navbar-inner - .container - %div.app_logo - = link_to root_path, class: "home has_bottom_tooltip", title: "Dashboard" do - = brand_header_logo - %h1.title= title - - %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} - %span.sr-only Toggle navigation - %i.fa.fa-bars - - .navbar-collapse.collapse - %ul.nav.navbar-nav - %li.hidden-sm.hidden-xs - = render "layouts/search" - %li.visible-sm.visible-xs - = link_to search_path, title: "Search", class: 'has_bottom_tooltip', 'data-original-title' => 'Search area' do - %i.fa.fa-search - %li - = link_to help_path, title: 'Help', class: 'has_bottom_tooltip', - 'data-original-title' => 'Help' do - %i.fa.fa-question-circle - %li - = link_to explore_root_path, title: "Explore", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do - %i.fa.fa-globe - %li - = link_to user_snippets_path(current_user), title: "Your snippets", class: 'has_bottom_tooltip', 'data-original-title' => 'Your snippets' do - %i.fa.fa-clipboard - - if current_user.is_admin? - %li - = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do - %i.fa.fa-cogs - - if current_user.can_create_project? - %li - = link_to new_project_path, title: "New project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project' do - %i.fa.fa-plus - %li - = link_to profile_path, title: "Profile settings", class: 'has_bottom_tooltip', 'data-original-title' => 'Profile settings"' do - %i.fa.fa-user - %li - = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Sign out", class: 'has_bottom_tooltip', 'data-original-title' => 'Sign out' do - %i.fa.fa-sign-out - %li.hidden-xs - = link_to current_user, class: "profile-pic has_bottom_tooltip", id: 'profile-pic', 'data-original-title' => 'Your profile' do - = image_tag avatar_icon(current_user.email, 60), alt: 'User activity' - -= render 'shared/outdated_browser' diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml deleted file mode 100644 index 3c58f10e759f30200430684c241545265cbe1e97..0000000000000000000000000000000000000000 --- a/app/views/layouts/_init_auto_complete.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -:javascript - GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(@project.namespace, @project, type: @noteable.class, type_id: params[:id])}" - GitLab.GfmAutoComplete.setup(); diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml deleted file mode 100644 index 422966cdc5556d22e1dae102fd17636f3da6e2d0..0000000000000000000000000000000000000000 --- a/app/views/layouts/_page.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -- if defined?(sidebar) - .page-with-sidebar{ class: nav_sidebar_class } - = render "layouts/broadcast" - .sidebar-wrapper - = render(sidebar) - .collapse-nav - = render partial: 'layouts/collapse_button' - .content-wrapper - .container-fluid - .content - = render "layouts/flash" - .clearfix - = yield -- else - .container.navless-container - .content - = yield - -= yield :embedded_scripts - -:coffeescript - $('.page-sidebar-collapsed .nav-sidebar a').tooltip placement: "right" - diff --git a/app/views/layouts/_page_title.html.haml b/app/views/layouts/_page_title.html.haml deleted file mode 100644 index 54da507476388cd697beb27ad2e7dca6bb5b68df..0000000000000000000000000000000000000000 --- a/app/views/layouts/_page_title.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -- if content_for?(:page-title) - = yield :page-title diff --git a/app/views/layouts/_piwik.html.haml b/app/views/layouts/_piwik.html.haml deleted file mode 100644 index 135e8daca266cca6e27fd2667b73e46be9d36c37..0000000000000000000000000000000000000000 --- a/app/views/layouts/_piwik.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -:javascript - var _paq = _paq || []; - _paq.push(["trackPageView"]); - _paq.push(["enableLinkTracking"]); - - (function() { - var u=(("https:" == document.location.protocol) ? "https" : "http") + "://#{extra_config.piwik_url}/"; - _paq.push(["setTrackerUrl", u+"piwik.php"]); - _paq.push(["setSiteId", "#{extra_config.piwik_site_id}"]); - var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript"; - g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s); - })(); diff --git a/app/views/layouts/_public_head_panel.html.haml b/app/views/layouts/_public_head_panel.html.haml deleted file mode 100644 index 3d6d2bfc00a9f4f4fd5232cfce0aa5a7d63a48b8..0000000000000000000000000000000000000000 --- a/app/views/layouts/_public_head_panel.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -%header.navbar.navbar-fixed-top.navbar-gitlab - .navbar-inner - .container - %div.app_logo - = link_to explore_root_path, class: "home" do - = brand_header_logo - %h1.title= title - - %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"} - %span.sr-only Toggle navigation - %i.fa.fa-bars - - - unless current_controller?('sessions') - .pull-right.hidden-xs - = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-new append-right-10' - - .navbar-collapse.collapse - %ul.nav.navbar-nav - %li.visible-xs - = link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes') - -= render 'shared/outdated_browser' diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml deleted file mode 100644 index 04f79846858dbe2c3b5094f57285e9db24b3ecb8..0000000000000000000000000000000000000000 --- a/app/views/layouts/_search.html.haml +++ /dev/null @@ -1,28 +0,0 @@ -.search - = form_tag search_path, method: :get, class: 'navbar-form pull-left' do |f| - = search_field_tag "search", nil, placeholder: search_placeholder, class: "search-input" - = hidden_field_tag :group_id, @group.try(:id) - - if @project && @project.persisted? - = hidden_field_tag :project_id, @project.id - - - if current_controller?(:issues) - = hidden_field_tag :scope, 'issues' - - elsif current_controller?(:merge_requests) - = hidden_field_tag :scope, 'merge_requests' - - elsif current_controller?(:wikis) - = hidden_field_tag :scope, 'wiki_blobs' - - else - = hidden_field_tag :search_code, true - - - if @snippet || @snippets - = hidden_field_tag :snippets, true - = hidden_field_tag :repository_ref, @ref - = button_tag 'Go' if ENV['RAILS_ENV'] == 'test' - .search-autocomplete-opts.hide{:'data-autocomplete-path' => search_autocomplete_path, :'data-autocomplete-project-id' => @project.try(:id), :'data-autocomplete-project-ref' => @ref } - -:javascript - $('.search-input').on('keyup', function(e) { - if (e.keyCode == 27) { - $('.search-input').blur() - } - }) diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml deleted file mode 100644 index ab84e87c300209e2a7d3a42c7c15e9d003d86f6c..0000000000000000000000000000000000000000 --- a/app/views/layouts/admin.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: "Admin area" - %body{class: "#{app_theme} admin", :'data-page' => body_data_page} - = render "layouts/head_panel", title: link_to("Admin area", admin_root_path) - = render 'layouts/page', sidebar: 'layouts/nav/admin' diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml deleted file mode 100644 index 6bd8ac4adb85e4e9b9e6d8469963c36b0dd20fb0..0000000000000000000000000000000000000000 --- a/app/views/layouts/application.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: "Dashboard" - %body{class: "#{app_theme} application", :'data-page' => body_data_page } - = render "layouts/head_panel", title: link_to("Dashboard", root_path) - = render 'layouts/page', sidebar: 'layouts/nav/dashboard' diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml deleted file mode 100644 index 6f805f1c9d1ccba4d3c62dae35b7d0e9e9399abf..0000000000000000000000000000000000000000 --- a/app/views/layouts/devise.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head" - %body.ui_mars.login-page.application - = render "layouts/broadcast" - = render "layouts/public_head_panel", title: '' - .container.navless-container - .content - = render "layouts/flash" - .row.prepend-top-20 - .col-sm-5.pull-right - = yield - .col-sm-7.brand-holder.pull-left - %h1 - = brand_title - - if brand_item - = brand_image - = brand_text - - else - %h3 Open source software to collaborate on code - - %p - Manage git repositories with fine grained access controls that keep your code secure. - Perform code reviews and enhance collaboration with merge requests. - Each project can also have an issue tracker and a wiki. - - - if extra_sign_in_text.present? - = markdown(extra_sign_in_text) - - %hr - .container - .footer-links - = link_to "Explore", explore_root_path - = link_to "Documentation", "http://doc.gitlab.com/" - = link_to "About GitLab", "https://about.gitlab.com/" diff --git a/app/views/layouts/errors.html.haml b/app/views/layouts/errors.html.haml deleted file mode 100644 index e51fd4cb8208e4e758d1a3776b55bdd97f922f95..0000000000000000000000000000000000000000 --- a/app/views/layouts/errors.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: "Error" - %body{class: "#{app_theme} application"} - = render "layouts/head_panel", title: "" if current_user - .container.navless-container - = render "layouts/flash" - .error-page - = yield diff --git a/app/views/layouts/explore.html.haml b/app/views/layouts/explore.html.haml deleted file mode 100644 index 2bd0b8d85c91b0e929ad7258eda7f791bbb82b89..0000000000000000000000000000000000000000 --- a/app/views/layouts/explore.html.haml +++ /dev/null @@ -1,30 +0,0 @@ -- page_title = 'Explore' -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: page_title - %body{class: "#{app_theme} application", :'data-page' => body_data_page} - = render "layouts/broadcast" - - if current_user - = render "layouts/head_panel", title: link_to(page_title, explore_root_path) - - else - = render "layouts/public_head_panel", title: link_to(page_title, explore_root_path) - .container.navless-container - .content - .explore-title - %h3 - Explore GitLab - %p.lead - Discover projects and groups. Share your projects with others - - - %ul.nav.nav-tabs - = nav_link(path: 'projects#trending') do - = link_to 'Trending Projects', explore_root_path - = nav_link(path: 'projects#starred') do - = link_to 'Most Starred Projects', starred_explore_projects_path - = nav_link(path: 'projects#index') do - = link_to 'All Projects', explore_projects_path - = nav_link(controller: :groups) do - = link_to 'All Groups', explore_groups_path - - = yield diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml deleted file mode 100644 index f4a6bee15f68c6e6022179bb4378e7bca15a64af..0000000000000000000000000000000000000000 --- a/app/views/layouts/group.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: group_head_title - %body{class: "#{app_theme} application", :'data-page' => body_data_page} - = render "layouts/head_panel", title: link_to(@group.name, group_path(@group)) - = render 'layouts/page', sidebar: 'layouts/nav/group' diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml deleted file mode 100644 index 34efceb37d1c64c6028ebb13e3558578065aa51a..0000000000000000000000000000000000000000 --- a/app/views/layouts/nav/_admin.html.haml +++ /dev/null @@ -1,65 +0,0 @@ -%ul.nav.nav-sidebar - = nav_link(controller: :dashboard, html_options: {class: 'home'}) do - = link_to admin_root_path, title: "Stats" do - %i.fa.fa-dashboard - %span - Overview - = nav_link(controller: :projects) do - = link_to admin_namespaces_projects_path, title: 'Projects' do - %i.fa.fa-cube - %span - Projects - = nav_link(controller: :users) do - = link_to admin_users_path, title: 'Users' do - %i.fa.fa-user - %span - Users - = nav_link(controller: :groups) do - = link_to admin_groups_path, title: 'Groups' do - %i.fa.fa-group - %span - Groups - = nav_link(controller: :deploy_keys) do - = link_to admin_deploy_keys_path, title: 'Deploy Keys' do - %i.fa.fa-key - %span - Deploy Keys - = nav_link(controller: :logs) do - = link_to admin_logs_path, title: 'Logs' do - %i.fa.fa-file-text - %span - Logs - = nav_link(controller: :broadcast_messages) do - = link_to admin_broadcast_messages_path, title: 'Broadcast Messages' do - %i.fa.fa-bullhorn - %span - Messages - = nav_link(controller: :hooks) do - = link_to admin_hooks_path, title: 'Hooks' do - %i.fa.fa-external-link - %span - Hooks - = nav_link(controller: :background_jobs) do - = link_to admin_background_jobs_path, title: 'Background Jobs' do - %i.fa.fa-cog - %span - Background Jobs - - = nav_link(controller: :applications) do - = link_to admin_applications_path, title: 'Applications' do - %i.fa.fa-cloud - %span - Applications - - = nav_link(controller: :services) do - = link_to admin_application_settings_services_path, title: 'Service Templates' do - %i.fa.fa-copy - %span - Service Templates - - = nav_link(controller: :application_settings, html_options: { class: 'separate-item'}) do - = link_to admin_application_settings_path, title: 'Settings' do - %i.fa.fa-cogs - %span - Settings - diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml deleted file mode 100644 index e4f630c6a18a317859c9cb33a8ea46dfa978813f..0000000000000000000000000000000000000000 --- a/app/views/layouts/nav/_dashboard.html.haml +++ /dev/null @@ -1,38 +0,0 @@ -%ul.nav.nav-sidebar - = nav_link(path: 'dashboard#show', html_options: {class: 'home'}) do - = link_to root_path, title: 'Home', class: 'shortcuts-activity' do - %i.fa.fa-dashboard - %span - Your Projects - = nav_link(path: 'projects#starred') do - = link_to starred_dashboard_projects_path, title: 'Starred Projects' do - %i.fa.fa-star - %span - Starred Projects - = nav_link(controller: :groups) do - = link_to dashboard_groups_path, title: 'Groups' do - %i.fa.fa-group - %span - Groups - = nav_link(controller: :milestones) do - = link_to dashboard_milestones_path, title: 'Milestones' do - %i.fa.fa-clock-o - %span - Milestones - = nav_link(path: 'dashboard#issues') do - = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues' do - %i.fa.fa-exclamation-circle - %span - Issues - %span.count= current_user.assigned_issues.opened.count - = nav_link(path: 'dashboard#merge_requests') do - = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests' do - %i.fa.fa-tasks - %span - Merge Requests - %span.count= current_user.assigned_merge_requests.opened.count - = nav_link(controller: :help) do - = link_to help_path, title: 'Help' do - %i.fa.fa-question-circle - %span - Help diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml deleted file mode 100644 index f0d92b7a12c45e31b032773ba7996729345aff70..0000000000000000000000000000000000000000 --- a/app/views/layouts/nav/_group.html.haml +++ /dev/null @@ -1,42 +0,0 @@ -%ul.nav.nav-sidebar - = nav_link(path: 'groups#show', html_options: {class: 'home'}) do - = link_to group_path(@group), title: "Home" do - %i.fa.fa-dashboard - %span - Activity - - if current_user - = nav_link(controller: [:group, :milestones]) do - = link_to group_milestones_path(@group), title: 'Milestones' do - %i.fa.fa-clock-o - %span - Milestones - = nav_link(path: 'groups#issues') do - = link_to issues_group_path(@group), title: 'Issues' do - %i.fa.fa-exclamation-circle - %span - Issues - - if current_user - %span.count= Issue.opened.of_group(@group).count - = nav_link(path: 'groups#merge_requests') do - = link_to merge_requests_group_path(@group), title: 'Merge Requests' do - %i.fa.fa-tasks - %span - Merge Requests - - if current_user - %span.count= MergeRequest.opened.of_group(@group).count - = nav_link(controller: [:group_members]) do - = link_to group_group_members_path(@group), title: 'Members' do - %i.fa.fa-users - %span - Members - - - if can?(current_user, :admin_group, @group) - = nav_link(html_options: { class: "#{"active" if group_settings_page?} separate-item" }) do - = link_to edit_group_path(@group), title: 'Settings', class: "tab no-highlight" do - %i.fa.fa-cogs - %span - Settings - %i.fa.fa-angle-down - - - if group_settings_page? - = render 'groups/settings_nav' diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml deleted file mode 100644 index d88e862829d6c44527d2b86a95efbe515287d8c0..0000000000000000000000000000000000000000 --- a/app/views/layouts/nav/_profile.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -%ul.nav.nav-sidebar - = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do - = link_to profile_path, title: "Profile" do - %i.fa.fa-user - %span - Profile - = nav_link(controller: :accounts) do - = link_to profile_account_path, title: 'Account' do - %i.fa.fa-gear - %span - Account - = nav_link(path: ['profiles#applications', 'applications#edit', 'applications#show', 'applications#new']) do - = link_to applications_profile_path, title: 'Applications' do - %i.fa.fa-cloud - %span - Applications - = nav_link(controller: :emails) do - = link_to profile_emails_path, title: 'Emails' do - %i.fa.fa-envelope-o - %span - Emails - %span.count= current_user.emails.count + 1 - - unless current_user.ldap_user? - = nav_link(controller: :passwords) do - = link_to edit_profile_password_path, title: 'Password' do - %i.fa.fa-lock - %span - Password - = nav_link(controller: :notifications) do - = link_to profile_notifications_path, title: 'Notifications' do - %i.fa.fa-inbox - %span - Notifications - - = nav_link(controller: :keys) do - = link_to profile_keys_path, title: 'SSH Keys' do - %i.fa.fa-key - %span - SSH Keys - %span.count= current_user.keys.count - = nav_link(path: 'profiles#design') do - = link_to design_profile_path, title: 'Design' do - %i.fa.fa-image - %span - Design - = nav_link(path: 'profiles#history') do - = link_to history_profile_path, title: 'History' do - %i.fa.fa-history - %span - History diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml deleted file mode 100644 index 6c13f30f62764ba7f79bd466a8e767391c0d4b46..0000000000000000000000000000000000000000 --- a/app/views/layouts/nav/_project.html.haml +++ /dev/null @@ -1,97 +0,0 @@ -%ul.project-navigation.nav.nav-sidebar - - if @project_settings_nav - = nav_link do - = link_to project_path(@project), title: 'Back to project', class: "" do - %i.fa.fa-caret-square-o-left - %span - Back to project - - %li.separate-item - - = render 'projects/settings_nav' - - - else - = nav_link(path: 'projects#show', html_options: {class: "home"}) do - = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do - %i.fa.fa-dashboard - %span - Project - - if project_nav_tab? :files - = nav_link(controller: %w(tree blob blame edit_tree new_tree)) do - = link_to namespace_project_tree_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Files', class: 'shortcuts-tree' do - %i.fa.fa-files-o - %span - Files - - - if project_nav_tab? :commits - = nav_link(controller: %w(commit commits compare repositories tags branches)) do - = link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Commits', class: 'shortcuts-commits' do - %i.fa.fa-history - %span - Commits - - - if project_nav_tab? :network - = nav_link(controller: %w(network)) do - = link_to namespace_project_network_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Network', class: 'shortcuts-network' do - %i.fa.fa-code-fork - %span - Network - - - if project_nav_tab? :graphs - = nav_link(controller: %w(graphs)) do - = link_to namespace_project_graph_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Graphs', class: 'shortcuts-graphs' do - %i.fa.fa-area-chart - %span - Graphs - - - if project_nav_tab? :milestones - = nav_link(controller: :milestones) do - = link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do - %i.fa.fa-clock-o - %span - Milestones - - - if project_nav_tab? :issues - = nav_link(controller: :issues) do - = link_to url_for_project_issues(@project, only_path: true), title: 'Issues', class: 'shortcuts-issues' do - %i.fa.fa-exclamation-circle - %span - Issues - - if @project.default_issues_tracker? - %span.count.issue_counter= @project.issues.opened.count - - - if project_nav_tab? :merge_requests - = nav_link(controller: :merge_requests) do - = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do - %i.fa.fa-tasks - %span - Merge Requests - %span.count.merge_counter= @project.merge_requests.opened.count - - - if project_nav_tab? :labels - = nav_link(controller: :labels) do - = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do - %i.fa.fa-tags - %span - Labels - - - if project_nav_tab? :wiki - = nav_link(controller: :wikis) do - = link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do - %i.fa.fa-book - %span - Wiki - - - if project_nav_tab? :snippets - = nav_link(controller: :snippets) do - = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do - %i.fa.fa-file-text-o - %span - Snippets - - - if project_nav_tab? :settings - = nav_link(html_options: {class: "#{project_tab_class} separate-item"}) do - = link_to edit_project_path(@project), title: 'Settings', class: "stat-tab tab no-highlight" do - %i.fa.fa-cogs - %span - Settings diff --git a/app/views/layouts/navless.html.haml b/app/views/layouts/navless.html.haml deleted file mode 100644 index 4d0278251a67ff87bd1914ceaed35437cd60ed17..0000000000000000000000000000000000000000 --- a/app/views/layouts/navless.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: @title - %body{class: "#{app_theme} application", :'data-page' => body_data_page} - = render "layouts/broadcast" - = render "layouts/head_panel", title: defined?(@title_url) ? link_to(@title, @title_url) : @title - .container.navless-container - .content - = render "layouts/flash" - = yield diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml deleted file mode 100644 index 00c7cedce40da9ea45d8a1a586681f8d4c022595..0000000000000000000000000000000000000000 --- a/app/views/layouts/notify.html.haml +++ /dev/null @@ -1,42 +0,0 @@ -%html{lang: "en"} - %head - %meta{content: "text/html; charset=utf-8", "http-equiv" => "Content-Type"} - %title - GitLab - :css - img { - max-width: 100%; - height: auto; - } - p.details { - font-style:italic; - color:#777 - } - .footer p { - font-size:small; - color:#777 - } - pre.commit-message { - white-space: pre-wrap; - } - .file-stats a { - text-decoration: none; - } - .file-stats .new-file { - color: #090; - } - .file-stats .deleted-file { - color: #B00; - }} - %body - %div.content - = yield - %div.footer{style: "margin-top: 10px;"} - %p - \— - %br - - if @target_url - #{link_to "View it on GitLab", @target_url} - = email_action @target_url - - if @project && !@disable_footer - You're receiving this notification because you are a member of the #{link_to_unless @target_url, @project.name_with_namespace, namespace_project_url(@project.namespace, @project)} project team. diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml deleted file mode 100644 index 2b5be7fc37202a5ea3735941d94a44a6f96c055d..0000000000000000000000000000000000000000 --- a/app/views/layouts/profile.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: "Profile" - %body{class: "#{app_theme} profile", :'data-page' => body_data_page} - = render "layouts/head_panel", title: link_to("Profile", profile_path) - = render 'layouts/page', sidebar: 'layouts/nav/profile' diff --git a/app/views/layouts/project_settings.html.haml b/app/views/layouts/project_settings.html.haml deleted file mode 100644 index 0a0039dec169e5f5d5d047685ebf29e1d7fbc8a3..0000000000000000000000000000000000000000 --- a/app/views/layouts/project_settings.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: @project.name_with_namespace - %body{class: "#{app_theme} project", :'data-page' => body_data_page, :'data-project-id' => @project.id } - = render "layouts/head_panel", title: project_title(@project) - = render "layouts/init_auto_complete" - - @project_settings_nav = true - = render 'layouts/page', sidebar: 'layouts/nav/project' diff --git a/app/views/layouts/projects.html.haml b/app/views/layouts/projects.html.haml deleted file mode 100644 index dde0964f47f4961035bcf2467b24438ee0602404..0000000000000000000000000000000000000000 --- a/app/views/layouts/projects.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: project_head_title - %body{class: "#{app_theme} project", :'data-page' => body_data_page, :'data-project-id' => @project.id } - = render "layouts/head_panel", title: project_title(@project) - = render "layouts/init_auto_complete" - = render 'layouts/page', sidebar: 'layouts/nav/project' diff --git a/app/views/layouts/public_group.html.haml b/app/views/layouts/public_group.html.haml deleted file mode 100644 index b9b1d03e08ee8a05288b207fcfbad755778f6da4..0000000000000000000000000000000000000000 --- a/app/views/layouts/public_group.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: group_head_title - %body{class: "#{app_theme} application", :'data-page' => body_data_page} - = render "layouts/public_head_panel", title: link_to(@group.name, group_path(@group)) - = render 'layouts/page', sidebar: 'layouts/nav/group' diff --git a/app/views/layouts/public_projects.html.haml b/app/views/layouts/public_projects.html.haml deleted file mode 100644 index 04fa7c84e73c75ccaf700be683062e90fa0ce75e..0000000000000000000000000000000000000000 --- a/app/views/layouts/public_projects.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: @project.name_with_namespace - %body{class: "#{app_theme} application", :'data-page' => body_data_page} - = render "layouts/public_head_panel", title: project_title(@project) - = render 'layouts/page', sidebar: 'layouts/nav/project' diff --git a/app/views/layouts/public_users.html.haml b/app/views/layouts/public_users.html.haml deleted file mode 100644 index 71c16bd168418d1a0771abe37c692c26f12178c5..0000000000000000000000000000000000000000 --- a/app/views/layouts/public_users.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: @title - %body{class: "#{app_theme} application", :'data-page' => body_data_page} - = render "layouts/public_head_panel", title: defined?(@title_url) ? link_to(@title, @title_url) : @title - = render 'layouts/page' diff --git a/app/views/layouts/search.html.haml b/app/views/layouts/search.html.haml deleted file mode 100644 index f9d8db06e10635c0023a48fe20b103b6a851e2d8..0000000000000000000000000000000000000000 --- a/app/views/layouts/search.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -!!! 5 -%html{ lang: "en"} - = render "layouts/head", title: "Search" - %body{class: "#{app_theme} application", :'data-page' => body_data_page} - = render "layouts/broadcast" - = render "layouts/head_panel", title: link_to("Search", search_path) - .container.navless-container - .content - = render "layouts/flash" - = yield diff --git a/app/views/notify/_note_message.html.haml b/app/views/notify/_note_message.html.haml deleted file mode 100644 index 3fd4b04ac8456a42f591a3f77fa197866e873c72..0000000000000000000000000000000000000000 --- a/app/views/notify/_note_message.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%div - = markdown(@note.note, reference_only_path: false) diff --git a/app/views/notify/_reassigned_issuable_email.html.haml b/app/views/notify/_reassigned_issuable_email.html.haml deleted file mode 100644 index 56d81b2ed2e074eddefce56844eddf3f241027d3..0000000000000000000000000000000000000000 --- a/app/views/notify/_reassigned_issuable_email.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%p - Assignee changed - - if @previous_assignee - from - %strong #{@previous_assignee.name} - to - - if issuable.assignee_id - %strong #{issuable.assignee_name} - - else - %strong Unassigned diff --git a/app/views/notify/_reassigned_issuable_email.text.erb b/app/views/notify/_reassigned_issuable_email.text.erb deleted file mode 100644 index 855d37429d9fe64adc541e280366f5901b23be9c..0000000000000000000000000000000000000000 --- a/app/views/notify/_reassigned_issuable_email.text.erb +++ /dev/null @@ -1,6 +0,0 @@ -Reassigned <%= issuable.class.model_name.human.titleize %> <%= issuable.iid %> - -<%= url_for([issuable.project.namespace.becomes(Namespace), issuable.project, issuable, {only_path: false}]) %> - -Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee -%> - to <%= "#{issuable.assignee_id ? issuable.assignee_name : 'Unassigned'}" %> diff --git a/app/views/notify/closed_issue_email.html.haml b/app/views/notify/closed_issue_email.html.haml deleted file mode 100644 index 56c18cd83cd6fc688b923d355a33050801518487..0000000000000000000000000000000000000000 --- a/app/views/notify/closed_issue_email.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%p - = "Issue was closed by #{@updated_by.name}" diff --git a/app/views/notify/closed_issue_email.text.haml b/app/views/notify/closed_issue_email.text.haml deleted file mode 100644 index ac703b31eddf5d4f6ea739612a122b1274f58902..0000000000000000000000000000000000000000 --- a/app/views/notify/closed_issue_email.text.haml +++ /dev/null @@ -1,3 +0,0 @@ -= "Issue was closed by #{@updated_by.name}" - -Issue ##{@issue.iid}: #{namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)} diff --git a/app/views/notify/closed_merge_request_email.html.haml b/app/views/notify/closed_merge_request_email.html.haml deleted file mode 100644 index 574e8bfef245a06fe81d8b1540ce683d5fc128de..0000000000000000000000000000000000000000 --- a/app/views/notify/closed_merge_request_email.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%p - = "Merge Request ##{@merge_request.iid} was closed by #{@updated_by.name}" diff --git a/app/views/notify/closed_merge_request_email.text.haml b/app/views/notify/closed_merge_request_email.text.haml deleted file mode 100644 index 59db86b08bc404062f8723b0fb6689e295b25bdb..0000000000000000000000000000000000000000 --- a/app/views/notify/closed_merge_request_email.text.haml +++ /dev/null @@ -1,8 +0,0 @@ -= "Merge Request ##{@merge_request.iid} was closed by #{@updated_by.name}" - -Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} - -= merge_path_description(@merge_request, 'to') - -Author: #{@merge_request.author_name} -Assignee: #{@merge_request.assignee_name} diff --git a/app/views/notify/group_access_granted_email.html.haml b/app/views/notify/group_access_granted_email.html.haml deleted file mode 100644 index f1916d624b6b35d9fabe1808660022197e8b324d..0000000000000000000000000000000000000000 --- a/app/views/notify/group_access_granted_email.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%p - = "You have been granted #{@group_member.human_access} access to group" - = link_to group_url(@group) do - = @group.name diff --git a/app/views/notify/group_access_granted_email.text.erb b/app/views/notify/group_access_granted_email.text.erb deleted file mode 100644 index ef9617bfc16ad3d47aa75524e5d28a379ca1639b..0000000000000000000000000000000000000000 --- a/app/views/notify/group_access_granted_email.text.erb +++ /dev/null @@ -1,4 +0,0 @@ - -You have been granted <%= @group_member.human_access %> access to group <%= @group.name %> - -<%= url_for(group_url(@group)) %> diff --git a/app/views/notify/group_invite_accepted_email.html.haml b/app/views/notify/group_invite_accepted_email.html.haml deleted file mode 100644 index 55efad384a79552ba51ee49935e04fcdc9a53c1e..0000000000000000000000000000000000000000 --- a/app/views/notify/group_invite_accepted_email.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%p - #{@group_member.invite_email}, now known as - #{link_to @group_member.user.name, user_url(@group_member.user)}, - has accepted your invitation to join group - #{link_to @group.name, group_url(@group)}. - diff --git a/app/views/notify/group_invite_accepted_email.text.erb b/app/views/notify/group_invite_accepted_email.text.erb deleted file mode 100644 index f8b70f7a5a60c8d617cd94e3db88a91da13c8007..0000000000000000000000000000000000000000 --- a/app/views/notify/group_invite_accepted_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= @group_member.invite_email %>, now known as <%= @group_member.user.name %>, has accepted your invitation to join group <%= @group.name %>. - -<%= group_url(@group) %> diff --git a/app/views/notify/group_invite_declined_email.html.haml b/app/views/notify/group_invite_declined_email.html.haml deleted file mode 100644 index f9525d84fac655d96f2dbaced015467d4bcad1fa..0000000000000000000000000000000000000000 --- a/app/views/notify/group_invite_declined_email.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%p - #{@invite_email} - has declined your invitation to join group - #{link_to @group.name, group_url(@group)}. - diff --git a/app/views/notify/group_invite_declined_email.text.erb b/app/views/notify/group_invite_declined_email.text.erb deleted file mode 100644 index 6c19a288d15fb2030a5c814645fbd4484156c276..0000000000000000000000000000000000000000 --- a/app/views/notify/group_invite_declined_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= @invite_email %> has declined your invitation to join group <%= @group.name %>. - -<%= group_url(@group) %> diff --git a/app/views/notify/group_member_invited_email.html.haml b/app/views/notify/group_member_invited_email.html.haml deleted file mode 100644 index 163e88bfea3b455a6fd478ed25236f703d681372..0000000000000000000000000000000000000000 --- a/app/views/notify/group_member_invited_email.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -%p - You have been invited - - if inviter = @group_member.created_by - by - = link_to inviter.name, user_url(inviter) - to join group - = link_to @group.name, group_url(@group) - as #{@group_member.human_access}. - -%p - = link_to 'Accept invitation', invite_url(@token) - or - = link_to 'decline', decline_invite_url(@token) - diff --git a/app/views/notify/group_member_invited_email.text.erb b/app/views/notify/group_member_invited_email.text.erb deleted file mode 100644 index 28ce4819b14eedf5132758b9e88db81bb6d10940..0000000000000000000000000000000000000000 --- a/app/views/notify/group_member_invited_email.text.erb +++ /dev/null @@ -1,4 +0,0 @@ -You have been invited <%= "by #{@group_member.created_by.name} " if @group_member.created_by %>to join group <%= @group.name %> as <%= @group_member.human_access %>. - -Accept invitation: <%= invite_url(@token) %> -Decline invitation: <%= decline_invite_url(@token) %> diff --git a/app/views/notify/issue_status_changed_email.html.haml b/app/views/notify/issue_status_changed_email.html.haml deleted file mode 100644 index 482c884a9dbde497e3101a5c0d53fbce9a9467ae..0000000000000000000000000000000000000000 --- a/app/views/notify/issue_status_changed_email.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%p - = "Issue was #{@issue_status} by #{@updated_by.name}" diff --git a/app/views/notify/issue_status_changed_email.text.erb b/app/views/notify/issue_status_changed_email.text.erb deleted file mode 100644 index e6ab3fcde7705471517f92f92114475ab90876c4..0000000000000000000000000000000000000000 --- a/app/views/notify/issue_status_changed_email.text.erb +++ /dev/null @@ -1,4 +0,0 @@ -Issue was <%= @issue_status %> by <%= @updated_by.name %> - -Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> - diff --git a/app/views/notify/merge_request_status_email.html.haml b/app/views/notify/merge_request_status_email.html.haml deleted file mode 100644 index c9bf04f514e107ac9565a8df8604943cf6251866..0000000000000000000000000000000000000000 --- a/app/views/notify/merge_request_status_email.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%p - = "Merge Request ##{@merge_request.iid} was #{@mr_status} by #{@updated_by.name}" diff --git a/app/views/notify/merge_request_status_email.text.haml b/app/views/notify/merge_request_status_email.text.haml deleted file mode 100644 index b96dd0fd8abb901acb088d37cfd2841c77c31fbd..0000000000000000000000000000000000000000 --- a/app/views/notify/merge_request_status_email.text.haml +++ /dev/null @@ -1,8 +0,0 @@ -= "Merge Request ##{@merge_request.iid} was #{@mr_status} by #{@updated_by.name}" - -Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} - -= merge_path_description(@merge_request, 'to') - -Author: #{@merge_request.author_name} -Assignee: #{@merge_request.assignee_name} diff --git a/app/views/notify/merged_merge_request_email.html.haml b/app/views/notify/merged_merge_request_email.html.haml deleted file mode 100644 index 6762fae7f64f3c7fd2c3394441341305572c6429..0000000000000000000000000000000000000000 --- a/app/views/notify/merged_merge_request_email.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -%p - = "Merge Request ##{@merge_request.iid} was merged" diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml deleted file mode 100644 index 9db75bdb19e48aff9b07415aedda6b07429fefcb..0000000000000000000000000000000000000000 --- a/app/views/notify/merged_merge_request_email.text.haml +++ /dev/null @@ -1,8 +0,0 @@ -= "Merge Request ##{@merge_request.iid} was merged" - -Merge Request Url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} - -= merge_path_description(@merge_request, 'to') - -Author: #{@merge_request.author_name} -Assignee: #{@merge_request.assignee_name} diff --git a/app/views/notify/new_email_email.html.haml b/app/views/notify/new_email_email.html.haml deleted file mode 100644 index 4a0448a573ccd2f9387174404e4301a84d0473da..0000000000000000000000000000000000000000 --- a/app/views/notify/new_email_email.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%p - Hi #{@user.name}! -%p - A new email was added to your account: -%p - email: - %code= @email.email -%p - If this email was added in error, you can remove it here: - = link_to "Emails", profile_emails_url diff --git a/app/views/notify/new_email_email.text.erb b/app/views/notify/new_email_email.text.erb deleted file mode 100644 index 51cba99ad0d695ed9ff107f7ebaf6b6d86a3a4a1..0000000000000000000000000000000000000000 --- a/app/views/notify/new_email_email.text.erb +++ /dev/null @@ -1,7 +0,0 @@ -Hi <%= @user.name %>! - -A new email was added to your account: - -email.................. <%= @email.email %> - -If this email was added in error, you can remove it here: <%= profile_emails_url %> diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml deleted file mode 100644 index 53a068be52e5b1c53a380f32a9bcf91cc480638e..0000000000000000000000000000000000000000 --- a/app/views/notify/new_issue_email.html.haml +++ /dev/null @@ -1,6 +0,0 @@ --if @issue.description - = markdown(@issue.description, reference_only_path: false) - -- if @issue.assignee_id.present? - %p - Assignee: #{@issue.assignee_name} diff --git a/app/views/notify/new_issue_email.text.erb b/app/views/notify/new_issue_email.text.erb deleted file mode 100644 index 0cc629354985870100d6ac548af74ffdc8ca8d40..0000000000000000000000000000000000000000 --- a/app/views/notify/new_issue_email.text.erb +++ /dev/null @@ -1,5 +0,0 @@ -New Issue was created. - -Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> -Author: <%= @issue.author_name %> -Asignee: <%= @issue.assignee_name %> diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml deleted file mode 100644 index 5b7dd117c16afd159c0a427bc7022dc2a83e04e3..0000000000000000000000000000000000000000 --- a/app/views/notify/new_merge_request_email.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -%p.details - != merge_path_description(@merge_request, '→') - -- if @merge_request.assignee_id.present? - %p - Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name} - --if @merge_request.description - = markdown(@merge_request.description, reference_only_path: false) diff --git a/app/views/notify/new_merge_request_email.text.erb b/app/views/notify/new_merge_request_email.text.erb deleted file mode 100644 index f08039ad045c39f745a2d2400823032f9a4a3d58..0000000000000000000000000000000000000000 --- a/app/views/notify/new_merge_request_email.text.erb +++ /dev/null @@ -1,8 +0,0 @@ -New Merge Request #<%= @merge_request.iid %> - -<%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)) %> - -<%= merge_path_description(@merge_request, 'to') %> -Author: <%= @merge_request.author_name %> -Asignee: <%= @merge_request.assignee_name %> - diff --git a/app/views/notify/new_ssh_key_email.html.haml b/app/views/notify/new_ssh_key_email.html.haml deleted file mode 100644 index 63b0cbbd2051a7deaf9bb7519848f382ed15621f..0000000000000000000000000000000000000000 --- a/app/views/notify/new_ssh_key_email.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%p - Hi #{@user.name}! -%p - A new public key was added to your account: -%p - title: - %code= @key.title -%p - If this key was added in error, you can remove it under - = link_to "SSH Keys", profile_keys_url diff --git a/app/views/notify/new_ssh_key_email.text.erb b/app/views/notify/new_ssh_key_email.text.erb deleted file mode 100644 index 05b551c89a02cddd9826da2ac0aed6129fd9b9d9..0000000000000000000000000000000000000000 --- a/app/views/notify/new_ssh_key_email.text.erb +++ /dev/null @@ -1,7 +0,0 @@ -Hi <%= @user.name %>! - -A new public key was added to your account: - -Title: <%= @key.title %> - -If this key was added in error, you can remove it at <%= profile_keys_url %> diff --git a/app/views/notify/new_user_email.html.haml b/app/views/notify/new_user_email.html.haml deleted file mode 100644 index ebbe98dd472fe38b2ac76d7181b6b9f85ba79b09..0000000000000000000000000000000000000000 --- a/app/views/notify/new_user_email.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -%p - Hi #{@user['name']}! -%p - - if Gitlab.config.gitlab.signup_enabled - Your account has been created successfully. - - else - The Administrator created an account for you. Now you are a member of the company GitLab application. -%p - login.......................................... - %code= @user['email'] - -- if @user.created_by_id - %p - = link_to "Click here to set your password", edit_password_url(@user, :reset_password_token => @token) diff --git a/app/views/notify/new_user_email.text.erb b/app/views/notify/new_user_email.text.erb deleted file mode 100644 index 96b26879a7720820b861fa6109b89574a5c37122..0000000000000000000000000000000000000000 --- a/app/views/notify/new_user_email.text.erb +++ /dev/null @@ -1,8 +0,0 @@ -Hi <%= @user.name %>! - -The Administrator created an account for you. Now you are a member of the company GitLab application. - -login.................. <%= @user.email %> -<% if @user.created_by_id %> - <%= link_to "Click here to set your password", edit_password_url(@user, :reset_password_token => @token) %> -<% end %> diff --git a/app/views/notify/note_commit_email.html.haml b/app/views/notify/note_commit_email.html.haml deleted file mode 100644 index 1d961e4424c6b5238902774678a6009d6d94b72f..0000000000000000000000000000000000000000 --- a/app/views/notify/note_commit_email.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -= render 'note_message' - diff --git a/app/views/notify/note_commit_email.text.erb b/app/views/notify/note_commit_email.text.erb deleted file mode 100644 index aaeaf5fdf731c498ea6a46f570b9e7e9c5e924f7..0000000000000000000000000000000000000000 --- a/app/views/notify/note_commit_email.text.erb +++ /dev/null @@ -1,9 +0,0 @@ -New comment for Commit <%= @commit.short_id %> - -<%= url_for(namespace_project_commit_url(@note.project.namespace, @note.project, id: @commit.id, anchor: "note_#{@note.id}")) %> - - -Author: <%= @note.author_name %> - -<%= @note.note %> - diff --git a/app/views/notify/note_issue_email.html.haml b/app/views/notify/note_issue_email.html.haml deleted file mode 100644 index 2fa2f7846611da52652a8307e29b3992409f1606..0000000000000000000000000000000000000000 --- a/app/views/notify/note_issue_email.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render 'note_message' diff --git a/app/views/notify/note_issue_email.text.erb b/app/views/notify/note_issue_email.text.erb deleted file mode 100644 index e33cbcd70f2298d4b286f825c61fc5f71e32c195..0000000000000000000000000000000000000000 --- a/app/views/notify/note_issue_email.text.erb +++ /dev/null @@ -1,9 +0,0 @@ -New comment for Issue <%= @issue.iid %> - -<%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue, anchor: "note_#{@note.id}")) %> - - -Author: <%= @note.author_name %> - -<%= @note.note %> - diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml deleted file mode 100644 index 65f0e4c4068fbb3fbcdb3d0f358b1a1c9064698e..0000000000000000000000000000000000000000 --- a/app/views/notify/note_merge_request_email.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- if @note.diff_file_name - %p.details - New comment on diff for - = link_to @note.diff_file_name, @target_url - \: - -= render 'note_message' diff --git a/app/views/notify/note_merge_request_email.text.erb b/app/views/notify/note_merge_request_email.text.erb deleted file mode 100644 index 1d1411992a653493d1b5fb1f35f584ee6b004efc..0000000000000000000000000000000000000000 --- a/app/views/notify/note_merge_request_email.text.erb +++ /dev/null @@ -1,9 +0,0 @@ -New comment for Merge Request <%= @merge_request.iid %> - -<%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request, anchor: "note_#{@note.id}")) %> - - -<%= @note.author_name %> - -<%= @note.note %> - diff --git a/app/views/notify/project_access_granted_email.html.haml b/app/views/notify/project_access_granted_email.html.haml deleted file mode 100644 index dfc30a2d360cd312cfdb959731994ea6cafa8138..0000000000000000000000000000000000000000 --- a/app/views/notify/project_access_granted_email.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%p - = "You have been granted #{@project_member.human_access} access to project" -%p - = link_to namespace_project_url(@project.namespace, @project) do - = @project.name_with_namespace diff --git a/app/views/notify/project_access_granted_email.text.erb b/app/views/notify/project_access_granted_email.text.erb deleted file mode 100644 index 68eb1611ba7e6f4e73faa8d09ca8de7d01892ba9..0000000000000000000000000000000000000000 --- a/app/views/notify/project_access_granted_email.text.erb +++ /dev/null @@ -1,4 +0,0 @@ - -You have been granted <%= @project_member.human_access %> access to project <%= @project.name_with_namespace %> - -<%= url_for(namespace_project_url(@project.namespace, @project)) %> diff --git a/app/views/notify/project_invite_accepted_email.html.haml b/app/views/notify/project_invite_accepted_email.html.haml deleted file mode 100644 index 7e58d30b10a89eaca450b4ee0cae8cd451dd1eff..0000000000000000000000000000000000000000 --- a/app/views/notify/project_invite_accepted_email.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%p - #{@project_member.invite_email}, now known as - #{link_to @project_member.user.name, user_url(@project_member.user)}, - has accepted your invitation to join project - #{link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project)}. - diff --git a/app/views/notify/project_invite_accepted_email.text.erb b/app/views/notify/project_invite_accepted_email.text.erb deleted file mode 100644 index fcbe752114dace69c69679b299f93cf1e3672751..0000000000000000000000000000000000000000 --- a/app/views/notify/project_invite_accepted_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= @project_member.invite_email %>, now known as <%= @project_member.user.name %>, has accepted your invitation to join project <%= @project.name_with_namespace %>. - -<%= namespace_project_url(@project.namespace, @project) %> diff --git a/app/views/notify/project_invite_declined_email.html.haml b/app/views/notify/project_invite_declined_email.html.haml deleted file mode 100644 index c2d7e6f6e3a0aed662a768042970f210c80099e2..0000000000000000000000000000000000000000 --- a/app/views/notify/project_invite_declined_email.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%p - #{@invite_email} - has declined your invitation to join project - #{link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project)}. - diff --git a/app/views/notify/project_invite_declined_email.text.erb b/app/views/notify/project_invite_declined_email.text.erb deleted file mode 100644 index 484687fa51cbeef4ea3527d3b96e62c3e6bc2117..0000000000000000000000000000000000000000 --- a/app/views/notify/project_invite_declined_email.text.erb +++ /dev/null @@ -1,3 +0,0 @@ -<%= @invite_email %> has declined your invitation to join project <%= @project.name_with_namespace %>. - -<%= namespace_project_url(@project.namespace, @project) %> diff --git a/app/views/notify/project_member_invited_email.html.haml b/app/views/notify/project_member_invited_email.html.haml deleted file mode 100644 index 79eb89616de49402bfdde544b88fcfa633248b10..0000000000000000000000000000000000000000 --- a/app/views/notify/project_member_invited_email.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%p - You have been invited - - if inviter = @project_member.created_by - by - = link_to inviter.name, user_url(inviter) - to join project - = link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project) - as #{@project_member.human_access}. - -%p - = link_to 'Accept invitation', invite_url(@token) - or - = link_to 'decline', decline_invite_url(@token) diff --git a/app/views/notify/project_member_invited_email.text.erb b/app/views/notify/project_member_invited_email.text.erb deleted file mode 100644 index e07062721158bb29e0a0131e03dd912224d708ff..0000000000000000000000000000000000000000 --- a/app/views/notify/project_member_invited_email.text.erb +++ /dev/null @@ -1,4 +0,0 @@ -You have been invited <%= "by #{@project_member.created_by.name} " if @project_member.created_by %>to join project <%= @project.name_with_namespace %> as <%= @project_member.human_access %>. - -Accept invitation: <%= invite_url(@token) %> -Decline invitation: <%= decline_invite_url(@token) %> diff --git a/app/views/notify/project_was_moved_email.html.haml b/app/views/notify/project_was_moved_email.html.haml deleted file mode 100644 index 3cd759f1f5766f91cc0f08414640bc767dcd59dc..0000000000000000000000000000000000000000 --- a/app/views/notify/project_was_moved_email.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -%p - Project was moved to another location -%p - The project is now located under - = link_to namespace_project_url(@project.namespace, @project) do - = @project.name_with_namespace -%p - To update the remote url in your local repository run (for ssh): -%p{ style: "background: #f5f5f5; padding:10px; border:1px solid #ddd" } - git remote set-url origin #{@project.ssh_url_to_repo} -%p - or for http(s): -%p{ style: "background: #f5f5f5; padding:10px; border:1px solid #ddd" } - git remote set-url origin #{@project.http_url_to_repo} -%br diff --git a/app/views/notify/project_was_moved_email.text.erb b/app/views/notify/project_was_moved_email.text.erb deleted file mode 100644 index b3f18b35a4d606a0b46dcddc9ffe3faafef02576..0000000000000000000000000000000000000000 --- a/app/views/notify/project_was_moved_email.text.erb +++ /dev/null @@ -1,10 +0,0 @@ -Project was moved to another location - -The project is now located under -<%= namespace_project_url(@project.namespace, @project) %> - - -To update the remote url in your local repository run (for ssh): - git remote set-url origin <%= @project.ssh_url_to_repo %> -or for http(s): - git remote set-url origin <%= @project.http_url_to_repo %> diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml deleted file mode 100644 index 498ba8b83651b2fd1ecfe1212b96fa7dc9cee651..0000000000000000000000000000000000000000 --- a/app/views/notify/reassigned_issue_email.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render 'reassigned_issuable_email', issuable: @issue diff --git a/app/views/notify/reassigned_issue_email.text.erb b/app/views/notify/reassigned_issue_email.text.erb deleted file mode 100644 index 710253be9842975d9d0e4d27948814d4d5c87768..0000000000000000000000000000000000000000 --- a/app/views/notify/reassigned_issue_email.text.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render 'reassigned_issuable_email', issuable: @issue %> diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml deleted file mode 100644 index 2a650130f59ce19c289bf2014d230e7acf72c195..0000000000000000000000000000000000000000 --- a/app/views/notify/reassigned_merge_request_email.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render 'reassigned_issuable_email', issuable: @merge_request diff --git a/app/views/notify/reassigned_merge_request_email.text.erb b/app/views/notify/reassigned_merge_request_email.text.erb deleted file mode 100644 index b5b4f1ff99a6b3128835d48891143643a2a390cc..0000000000000000000000000000000000000000 --- a/app/views/notify/reassigned_merge_request_email.text.erb +++ /dev/null @@ -1 +0,0 @@ -<%= render 'reassigned_issuable_email', issuable: @merge_request %> diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml deleted file mode 100644 index a374a662333248d89faeb25e811a47cc03f2b429..0000000000000000000000000000000000000000 --- a/app/views/notify/repository_push_email.html.haml +++ /dev/null @@ -1,66 +0,0 @@ -%h3 #{@author.name} #{@action_name} #{@ref_type} #{@ref_name} at #{link_to @project.name_with_namespace, namespace_project_url(@project.namespace, @project)} - -- if @compare - - if @reverse_compare - %p - %strong WARNING: - The push did not contain any new commits, but force pushed to delete the commits and changes below. - - %h4 - = @reverse_compare ? "Deleted commits:" : "Commits:" - - %ul - - @commits.each do |commit| - %li - %strong #{link_to commit.short_id, namespace_project_commit_url(@project.namespace, @project, commit)} - %div - %span by #{commit.author_name} - %i at #{commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ")} - %pre.commit-message - = commit.safe_message - - %h4 #{pluralize @diffs.count, "changed file"}: - - %ul - - @diffs.each_with_index do |diff, i| - %li.file-stats - %a{href: "#{@target_url if @disable_diffs}#diff-#{i}" } - - if diff.deleted_file - %span.deleted-file - − - = diff.old_path - - elsif diff.renamed_file - = diff.old_path - → - = diff.new_path - - elsif diff.new_file - %span.new-file - + - = diff.new_path - - else - = diff.new_path - - - unless @disable_diffs - %h4 Changes: - - @diffs.each_with_index do |diff, i| - %li{id: "diff-#{i}"} - %a{href: @target_url + "#diff-#{i}"} - - if diff.deleted_file - %strong - = diff.old_path - deleted - - elsif diff.renamed_file - %strong - = diff.old_path - → - %strong - = diff.new_path - - else - %strong - = diff.new_path - %hr - = color_email_diff(diff.diff) - %br - - - if @compare.timeout - %h5 Huge diff. To prevent performance issues changes are hidden diff --git a/app/views/notify/repository_push_email.text.haml b/app/views/notify/repository_push_email.text.haml deleted file mode 100644 index 97a176ed2a3800577ce0ec8340c0c6d7428c41dc..0000000000000000000000000000000000000000 --- a/app/views/notify/repository_push_email.text.haml +++ /dev/null @@ -1,49 +0,0 @@ -#{@author.name} #{@action_name} #{@ref_type} #{@ref_name} at #{@project.name_with_namespace} -- if @compare - \ - \ - - if @reverse_compare - WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below. - \ - \ - = @reverse_compare ? "Deleted commits:" : "Commits:" - - @commits.each do |commit| - #{commit.short_id} by #{commit.author_name} at #{commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ")} - #{commit.safe_message} - \- - - - - - \ - \ - #{pluralize @diffs.count, "changed file"}: - \ - - @diffs.each do |diff| - - if diff.deleted_file - \- − #{diff.old_path} - - elsif diff.renamed_file - \- #{diff.old_path} → #{diff.new_path} - - elsif diff.new_file - \- + #{diff.new_path} - - else - \- #{diff.new_path} - - unless @disable_diffs - \ - \ - Changes: - - @diffs.each do |diff| - \ - \===================================== - - if diff.deleted_file - #{diff.old_path} deleted - - elsif diff.renamed_file - #{diff.old_path} → #{diff.new_path} - - else - = diff.new_path - \===================================== - != diff.diff - - if @compare.timeout - \ - \ - Huge diff. To prevent performance issues it was hidden - - if @target_url - \ - \ - View it on GitLab: #{@target_url} diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml deleted file mode 100644 index 5bffb4acc1d7530c08a00d699be68843c1680684..0000000000000000000000000000000000000000 --- a/app/views/profiles/accounts/show.html.haml +++ /dev/null @@ -1,77 +0,0 @@ -- if current_user.ldap_user? - .alert.alert-info - Some options are unavailable for LDAP accounts - -.account-page - %fieldset.update-token - %legend - Reset Private token - %div - = form_for @user, url: reset_private_token_profile_path, method: :put do |f| - .data - %p - Your private token is used to access application resources without authentication. - %br - It can be used for atom feeds or the API. - %span.cred - Keep it secret! - - %p.cgray - - if current_user.private_token - = text_field_tag "token", current_user.private_token, class: "form-control" - %div - = f.submit 'Reset private token', data: { confirm: "Are you sure?" }, class: "btn btn-primary btn-build-token" - - else - %span You don`t have one yet. Click generate to fix it. - = f.submit 'Generate', class: "btn success btn-build-token" - - - - if show_profile_social_tab? - %fieldset - %legend Connected Accounts - .oauth-buttons.append-bottom-10 - %p Click on icon to activate signin with one of the following services - - enabled_social_providers.each do |provider| - .btn-group - = link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider), - class: "btn btn-lg #{'active' if oauth_active?(provider)}" - - if oauth_active?(provider) - = link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do - %i.fa.fa-close - - - if show_profile_username_tab? - %fieldset.update-username - %legend - Change Username - = form_for @user, url: update_username_profile_path, method: :put, remote: true do |f| - %p - Changing your username will change path to all personal projects! - %div - = f.text_field :username, required: true, class: 'form-control' -   - .loading-gif.hide - %p - %i.fa.fa-spinner.fa-spin - Saving new username - %p.light - = user_url(@user) - %div - = f.submit 'Save username', class: "btn btn-warning" - - - if show_profile_remove_tab? - %fieldset.remove-account - %legend - Remove account - %div - %p Deleting an account has the following effects: - %ul - %li All user content like authored issues, snippets, comments will be removed - - rp = current_user.personal_projects.count - - unless rp.zero? - %li #{pluralize rp, 'personal project'} will be removed and cannot be restored - - if current_user.solo_owned_groups.present? - %li - The following groups will be abandoned. You should transfer or remove them: - %strong #{current_user.solo_owned_groups.map(&:name).join(', ')} - = link_to 'Delete account', user_registration_path, data: { confirm: "REMOVE #{current_user.name}? Are you sure?" }, method: :delete, class: "btn btn-remove" - diff --git a/app/views/profiles/applications.html.haml b/app/views/profiles/applications.html.haml deleted file mode 100644 index 97e98948f36647b7021e32cd3bd7e769365f75c0..0000000000000000000000000000000000000000 --- a/app/views/profiles/applications.html.haml +++ /dev/null @@ -1,49 +0,0 @@ -%h3.page-title - Application Settings -%p.light - OAuth2 protocol settings below. - -%fieldset.oauth-applications - %legend Your applications - %p= link_to 'New Application', new_oauth_application_path, class: 'btn btn-success' - - if @applications.any? - %table.table.table-striped - %thead - %tr - %th Name - %th Callback URL - %th Clients - %th - %th - %tbody - - @applications.each do |application| - %tr{:id => "application_#{application.id}"} - %td= link_to application.name, oauth_application_path(application) - %td - - application.redirect_uri.split.each do |uri| - %div= uri - %td= application.access_tokens.count - %td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link btn-sm' - %td= render 'doorkeeper/applications/delete_form', application: application - -%fieldset.oauth-authorized-applications.prepend-top-20 - %legend Authorized applications - - - if @authorized_tokens.any? - %table.table.table-striped - %thead - %tr - %th Name - %th Authorized At - %th Scope - %th - %tbody - - @authorized_apps.each do |app| - - token = app.authorized_tokens.order('created_at desc').first - %tr{:id => "application_#{app.id}"} - %td= app.name - %td= token.created_at - %td= token.scopes - %td= render 'doorkeeper/authorized_applications/delete_form', application: app - - else - %p.light You dont have any authorized applications diff --git a/app/views/profiles/design.html.haml b/app/views/profiles/design.html.haml deleted file mode 100644 index cc00d08d03b526230d2a8566801d8ea0139c9da4..0000000000000000000000000000000000000000 --- a/app/views/profiles/design.html.haml +++ /dev/null @@ -1,53 +0,0 @@ -%h3.page-title - Design Settings -%p.light - Appearance settings will be saved to your profile and made available across all devices. -%hr - -= form_for @user, url: profile_path, remote: true, method: :put do |f| - %fieldset.application-theme - %legend - Application theme - .themes_opts - = label_tag do - .prev.default - = f.radio_button :theme_id, 1 - Default - - = label_tag do - .prev.classic - = f.radio_button :theme_id, 2 - Classic - - = label_tag do - .prev.modern - = f.radio_button :theme_id, 3 - Modern - - = label_tag do - .prev.gray - = f.radio_button :theme_id, 4 - Gray - - = label_tag do - .prev.violet - = f.radio_button :theme_id, 5 - Violet - - = label_tag do - .prev.blue - = f.radio_button :theme_id, 6 - Blue - %br - .clearfix - - %fieldset.code-preview-theme - %legend - Code preview theme - .code_highlight_opts - - color_schemes.each do |color_scheme_id, color_scheme| - = label_tag do - .prev - = image_tag "#{color_scheme}-scheme-preview.png" - = f.radio_button :color_scheme_id, color_scheme_id - = color_scheme.gsub(/[-_]+/, ' ').humanize diff --git a/app/views/profiles/emails/index.html.haml b/app/views/profiles/emails/index.html.haml deleted file mode 100644 index 09f290429eacb2f97599daf3ea46e26df180fd15..0000000000000000000000000000000000000000 --- a/app/views/profiles/emails/index.html.haml +++ /dev/null @@ -1,41 +0,0 @@ -%h3.page-title - Email Settings -%p.light - Your - %b Primary Email - will be used for avatar detection and web based operations, such as edits and merges. - %br - Your - %b Notification Email - will be used for account notifications. - %br - All email addresses will be used to identify your commits. - -%hr - -.panel.panel-default - .panel-heading - Emails (#{@emails.count + 1}) - %ul.well-list#emails-table - %li - %strong= @primary - %span.label.label-success Primary Email - - if @primary === @public_email - %span.label.label-info Public Email - - @emails.each do |email| - %li - %strong= email.email - - if email.email === @public_email - %span.label.label-info Public Email - %span.cgray - added #{time_ago_with_tooltip(email.created_at)} - = link_to 'Remove', profile_email_path(email), data: { confirm: 'Are you sure?'}, method: :delete, class: 'btn btn-sm btn-remove pull-right' - -%h4 Add email address -= form_for 'email', url: profile_emails_path, html: { class: 'form-horizontal' } do |f| - .form-group - = f.label :email, class: 'control-label' - .col-sm-10 - = f.text_field :email, class: 'form-control' - .form-actions - = f.submit 'Add email address', class: 'btn btn-create' diff --git a/app/views/profiles/history.html.haml b/app/views/profiles/history.html.haml deleted file mode 100644 index b1ab433f48fb90552dd70f288b7a62fd86c34e50..0000000000000000000000000000000000000000 --- a/app/views/profiles/history.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%h3.page-title - Your Account History -%p.light - All events created by your account are listed below. -%hr -.profile_history - = render @events -%hr -= paginate @events, theme: "gitlab" - diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml deleted file mode 100644 index f905417f0e2bf905705b939f19fe3235decc51a6..0000000000000000000000000000000000000000 --- a/app/views/profiles/keys/_form.html.haml +++ /dev/null @@ -1,21 +0,0 @@ -%div - = form_for [:profile, @key], html: { class: 'form-horizontal' } do |f| - - if @key.errors.any? - .alert.alert-danger - %ul - - @key.errors.full_messages.each do |msg| - %li= msg - - .form-group - = f.label :title, class: 'control-label' - .col-sm-10= f.text_field :title, class: "form-control" - .form-group - = f.label :key, class: 'control-label' - .col-sm-10 - = f.text_area :key, class: "form-control", rows: 8 - - - .form-actions - = f.submit 'Add key', class: "btn btn-create" - = link_to "Cancel", profile_keys_path, class: "btn btn-cancel" - diff --git a/app/views/profiles/keys/_key.html.haml b/app/views/profiles/keys/_key.html.haml deleted file mode 100644 index fe5770f45c383d54ae38223a193facfaa361d5d4..0000000000000000000000000000000000000000 --- a/app/views/profiles/keys/_key.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -%tr - %td - = link_to path_to_key(key, is_admin) do - %strong= key.title - %td - %span - (#{key.fingerprint}) - %td - %span.cgray - added #{time_ago_with_tooltip(key.created_at)} - %td - = link_to 'Remove', path_to_key(key, is_admin), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-sm btn-remove delete-key pull-right" diff --git a/app/views/profiles/keys/_key_details.html.haml b/app/views/profiles/keys/_key_details.html.haml deleted file mode 100644 index 8bac22a2e1a8130d1a3a4169d509871b792b39fe..0000000000000000000000000000000000000000 --- a/app/views/profiles/keys/_key_details.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -- is_admin = defined?(admin) ? true : false -.row - .col-md-4 - .panel.panel-default - .panel-heading - SSH Key - %ul.well-list - %li - %span.light Title: - %strong= @key.title - %li - %span.light Created on: - %strong= @key.created_at.stamp("Aug 21, 2011") - - .col-md-8 - %p - %span.light Fingerprint: - %strong= @key.fingerprint - %pre.well-pre - = @key.key - .pull-right - = link_to 'Remove', path_to_key(@key, is_admin), data: {confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove delete-key" diff --git a/app/views/profiles/keys/_key_table.html.haml b/app/views/profiles/keys/_key_table.html.haml deleted file mode 100644 index ef0075aad3b20598c45a21fed3453a8cd65131b6..0000000000000000000000000000000000000000 --- a/app/views/profiles/keys/_key_table.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -- is_admin = defined?(admin) ? true : false -.panel.panel-default - - if @keys.any? - %table.table - %thead.panel-heading - %tr - %th Title - %th Fingerprint - %th Added at - %th - %tbody - - @keys.each do |key| - = render 'profiles/keys/key', key: key, is_admin: is_admin - - else - .nothing-here-block - - if is_admin - User has no ssh keys - - else - There are no SSH keys with access to your account. diff --git a/app/views/profiles/keys/index.html.haml b/app/views/profiles/keys/index.html.haml deleted file mode 100644 index 0904c50c88b99e8fffa697fa317c30786cc2b474..0000000000000000000000000000000000000000 --- a/app/views/profiles/keys/index.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%h3.page-title - SSH Keys Settings - .pull-right - = link_to "Add SSH Key", new_profile_key_path, class: "btn btn-new" -%p.light - Before you can add an SSH key you need to - = link_to "generate it.", help_page_path("ssh", "README") -%hr - -= render 'key_table' diff --git a/app/views/profiles/keys/new.html.haml b/app/views/profiles/keys/new.html.haml deleted file mode 100644 index ccec716d0c66f02c9c6d86e6802251ea668a5740..0000000000000000000000000000000000000000 --- a/app/views/profiles/keys/new.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -%h3.page-title Add an SSH Key -%p.light - Paste your public key here. Read more about how to generate a key on #{link_to "the SSH help page", help_page_path("ssh", "README")}. -%hr -= render 'form' - -:javascript - $('#key_key').on('focusout', function(){ - var title = $('#key_title'), - val = $('#key_key').val(), - comment = val.match(/^\S+ \S+ (.+)$/); - - if( comment && comment.length > 1 && title.val() == '' ){ - $('#key_title').val( comment[1] ); - } - }); diff --git a/app/views/profiles/keys/show.html.haml b/app/views/profiles/keys/show.html.haml deleted file mode 100644 index cfd53298962f50c7b1fd064a3421568ad8084e3d..0000000000000000000000000000000000000000 --- a/app/views/profiles/keys/show.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "key_details" diff --git a/app/views/profiles/notifications/_settings.html.haml b/app/views/profiles/notifications/_settings.html.haml deleted file mode 100644 index 2c85d2a9b2bb6223f033fafd3a24f99105c68f75..0000000000000000000000000000000000000000 --- a/app/views/profiles/notifications/_settings.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -%li - %span.notification.fa.fa-holder - - if notification.global? - = notification_icon(@notification) - - else - = notification_icon(notification) - - %span.str-truncated - - if membership.kind_of? GroupMember - = link_to membership.group.name, membership.group - - else - = link_to_project(membership.project) - .pull-right - = form_tag profile_notifications_path, method: :put, remote: true, class: 'update-notifications' do - = hidden_field_tag :notification_type, type, id: dom_id(membership, 'notification_type') - = hidden_field_tag :notification_id, membership.id, id: dom_id(membership, 'notification_id') - = select_tag :notification_level, options_for_select(Notification.options_with_labels, notification.level), class: 'trigger-submit' diff --git a/app/views/profiles/notifications/show.html.haml b/app/views/profiles/notifications/show.html.haml deleted file mode 100644 index 273e72f8a4dfc26bf133cbc98afeee4c4107b6a0..0000000000000000000000000000000000000000 --- a/app/views/profiles/notifications/show.html.haml +++ /dev/null @@ -1,78 +0,0 @@ -%h3.page-title - Notifications Settings -%p.light - These are your global notification settings. -%hr - -= form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications form-horizontal global-notifications-form' } do |f| - -if @user.errors.any? - %div.alert.alert-danger - %ul - - @user.errors.full_messages.each do |msg| - %li= msg - - = hidden_field_tag :notification_type, 'global' - - .form-group - = f.label :notification_email, class: "control-label" - .col-sm-10 - = f.select :notification_email, @user.all_emails, { include_blank: false }, class: "form-control" - - .form-group - = f.label :notification_level, class: 'control-label' - .col-sm-10 - .radio - = f.label :notification_level, value: Notification::N_DISABLED do - = f.radio_button :notification_level, Notification::N_DISABLED - .level-title - Disabled - %p You will not get any notifications via email - - .radio - = f.label :notification_level, value: Notification::N_MENTION do - = f.radio_button :notification_level, Notification::N_MENTION - .level-title - Mention - %p You will receive notifications only for comments in which you were @mentioned - - .radio - = f.label :notification_level, value: Notification::N_PARTICIPATING do - = f.radio_button :notification_level, Notification::N_PARTICIPATING - .level-title - Participating - %p You will only receive notifications from related resources (e.g. from your commits or assigned issues) - - .radio - = f.label :notification_level, value: Notification::N_WATCH do - = f.radio_button :notification_level, Notification::N_WATCH - .level-title - Watch - %p You will receive all notifications from projects in which you participate - - .form-actions - = f.submit 'Save changes', class: "btn btn-create" - -.clearfix - %hr -.row.all-notifications - .col-md-6 - %p - You can also specify notification level per group or per project. - %br - By default, all projects and groups will use the notification level set above. - %h4 Groups: - %ul.bordered-list - - @group_members.each do |group_member| - - notification = Notification.new(group_member) - = render 'settings', type: 'group', membership: group_member, notification: notification - - .col-md-6 - %p - To specify the notification level per project of a group you belong to, - %br - you need to be a member of the project itself, not only its group. - %h4 Projects: - %ul.bordered-list - - @project_members.each do |project_member| - - notification = Notification.new(project_member) - = render 'settings', type: 'project', membership: project_member, notification: notification diff --git a/app/views/profiles/notifications/update.js.haml b/app/views/profiles/notifications/update.js.haml deleted file mode 100644 index 84c6ab25599e4356f30a14c33264d884a51b3e07..0000000000000000000000000000000000000000 --- a/app/views/profiles/notifications/update.js.haml +++ /dev/null @@ -1,6 +0,0 @@ -- if @saved - :plain - new Flash("Notification settings saved", "notice") -- else - :plain - new Flash("Failed to save new settings", "alert") diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml deleted file mode 100644 index 4b04b113e89bd35066320a600811ad8a679210c3..0000000000000000000000000000000000000000 --- a/app/views/profiles/passwords/edit.html.haml +++ /dev/null @@ -1,38 +0,0 @@ -%h3.page-title Password Settings -%p.light - - if @user.password_automatically_set? - Set your password. - - else - Change your password or recover your current one. -%hr -.update-password - = form_for @user, url: profile_password_path, method: :put, html: { class: 'form-horizontal' } do |f| - %div - %p.slead - - unless @user.password_automatically_set? - You must provide current password in order to change it. - %br - After a successful password update, you will be redirected to the login page where you can log in with your new password. - -if @user.errors.any? - .alert.alert-danger - %ul - - @user.errors.full_messages.each do |msg| - %li= msg - - unless @user.password_automatically_set? - .form-group - = f.label :current_password, class: 'control-label' - .col-sm-10 - = f.password_field :current_password, required: true, class: 'form-control' - %div - = link_to "Forgot your password?", reset_profile_password_path, method: :put - - .form-group - = f.label :password, 'New password', class: 'control-label' - .col-sm-10 - = f.password_field :password, required: true, class: 'form-control' - .form-group - = f.label :password_confirmation, class: 'control-label' - .col-sm-10 - = f.password_field :password_confirmation, required: true, class: 'form-control' - .form-actions - = f.submit 'Save password', class: "btn btn-create" diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml deleted file mode 100644 index 8bed6e0dbee1f4fcd1e21fd1c3a654a5402324e5..0000000000000000000000000000000000000000 --- a/app/views/profiles/passwords/new.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -%h3.page-title Setup new password -%hr -= form_for @user, url: profile_password_path, method: :post, html: { class: 'form-horizontal '} do |f| - %p.slead - Please set a new password before proceeding. - %br - After a successful password update you will be redirected to login screen. - -if @user.errors.any? - .alert.alert-danger - %ul - - @user.errors.full_messages.each do |msg| - %li= msg - - - unless @user.password_automatically_set? - .form-group - = f.label :current_password, class: 'control-label' - .col-sm-10= f.password_field :current_password, required: true, class: 'form-control' - .form-group - = f.label :password, class: 'control-label' - .col-sm-10= f.password_field :password, required: true, class: 'form-control' - .form-group - = f.label :password_confirmation, class: 'control-label' - .col-sm-10 - = f.password_field :password_confirmation, required: true, class: 'form-control' - .form-actions - = f.submit 'Set new password', class: "btn btn-create" diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml deleted file mode 100644 index 6c745e69e4061fe83bd5a5393dc7bfc2ee57b93e..0000000000000000000000000000000000000000 --- a/app/views/profiles/show.html.haml +++ /dev/null @@ -1,110 +0,0 @@ -%h3.page-title - Profile Settings -%p.light - This information will appear on your profile. - - if current_user.ldap_user? - Some options are unavailable for LDAP accounts -%hr - - - -= form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" }, authenticity_token: true do |f| - -if @user.errors.any? - %div.alert.alert-danger - %ul - - @user.errors.full_messages.each do |msg| - %li= msg - .row - .col-md-7 - .form-group - = f.label :name, class: "control-label" - .col-sm-10 - = f.text_field :name, class: "form-control", required: true - %span.help-block Enter your name, so people you know can recognize you. - - .form-group - = f.label :email, class: "control-label" - .col-sm-10 - - if @user.ldap_user? - = f.text_field :email, class: "form-control", required: true, readonly: true - %span.help-block.light - Email is read-only for LDAP user - - else - - if @user.temp_oauth_email? - = f.text_field :email, class: "form-control", required: true, value: nil - - else - = f.text_field :email, class: "form-control", required: true - - if @user.unconfirmed_email.present? - %span.help-block - Please click the link in the confirmation email before continuing, it was sent to - %strong #{@user.unconfirmed_email} - - - else - %span.help-block We also use email for avatar detection if no avatar is uploaded. - .form-group - = f.label :public_email, class: "control-label" - .col-sm-10 - = f.select :public_email, options_for_select(@user.all_emails, selected: @user.public_email), {include_blank: 'Do not show in profile'}, class: "form-control" - %span.help-block This email will be displayed on your public profile. - .form-group - = f.label :skype, class: "control-label" - .col-sm-10= f.text_field :skype, class: "form-control" - .form-group - = f.label :linkedin, class: "control-label" - .col-sm-10= f.text_field :linkedin, class: "form-control" - .form-group - = f.label :twitter, class: "control-label" - .col-sm-10= f.text_field :twitter, class: "form-control" - .form-group - = f.label :website_url, 'Website', class: "control-label" - .col-sm-10= f.text_field :website_url, class: "form-control" - .form-group - = f.label :location, 'Location', class: "control-label" - .col-sm-10= f.text_field :location, class: "form-control" - .form-group - = f.label :bio, class: "control-label" - .col-sm-10 - = f.text_area :bio, rows: 4, class: "form-control", maxlength: 250 - %span.help-block Tell us about yourself in fewer than 250 characters. - - .col-md-5 - .light-well - = image_tag avatar_icon(@user.email, 160), alt: '', class: 'avatar s160' - - .clearfix - .profile-avatar-form-option - %p.light - - if @user.avatar? - You can change your avatar here - - if Gitlab.config.gravatar.enabled - %br - or remove the current avatar to revert to #{link_to "gravatar.com", "http://gravatar.com"} - - else - You can upload an avatar here - - if Gitlab.config.gravatar.enabled - %br - or change it at #{link_to "gravatar.com", "http://gravatar.com"} - %hr - %a.choose-btn.btn.btn-sm.js-choose-user-avatar-button - %i.fa.fa-paperclip - %span Choose File ... -   - %span.file_name.js-avatar-filename File name... - = f.file_field :avatar, class: "js-user-avatar-input hidden" - .light The maximum file size allowed is 200KB. - - if @user.avatar? - %hr - = link_to 'Remove avatar', profile_avatar_path, data: { confirm: "Avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" - - - if @user.public_profile? - .alert.alert-info - %h4 Public profile - %p Your profile is publicly visible because you joined public project(s) - - - .row - .col-md-7 - .form-group - .col-sm-2   - .col-sm-10 - = f.submit 'Save changes', class: "btn btn-success" diff --git a/app/views/profiles/update.js.erb b/app/views/profiles/update.js.erb deleted file mode 100644 index e664ac2a52ab81cd0cb1f128664ff86909bb8ab3..0000000000000000000000000000000000000000 --- a/app/views/profiles/update.js.erb +++ /dev/null @@ -1,9 +0,0 @@ -// Remove body class for any previous theme, re-add current one -$('body').removeClass('ui_basic ui_mars ui_modern ui_gray ui_color light_theme dark_theme') -$('body').addClass('<%= app_theme %> <%= theme_type %>') - -// Re-render the header to reflect the new theme -$('header').html('<%= escape_javascript(render("layouts/head_panel", title: "Profile")) %>') - -// Re-initialize header tooltips -$('.has_bottom_tooltip').tooltip({placement: 'bottom'}) diff --git a/app/views/profiles/update_username.js.haml b/app/views/profiles/update_username.js.haml deleted file mode 100644 index 249680bcab6634f7dfd9d7806058053a1a91c9c9..0000000000000000000000000000000000000000 --- a/app/views/profiles/update_username.js.haml +++ /dev/null @@ -1,6 +0,0 @@ -- if @user.valid? - :plain - new Flash("Username sucessfully changed", "notice") -- else - :plain - new Flash("Username change failed - #{@user.errors.full_messages.first}", "alert") diff --git a/app/views/projects/_bitbucket_import_modal.html.haml b/app/views/projects/_bitbucket_import_modal.html.haml deleted file mode 100644 index 07d4d602769b7d07fdd6f5968f3e93c9c6990cd2..0000000000000000000000000000000000000000 --- a/app/views/projects/_bitbucket_import_modal.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%div#bitbucket_import_modal.modal.hide - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3 Import projects from Bitbucket - .modal-body - To enable importing projects from Bitbucket, - - if current_user.admin? - you need to - - else - your GitLab administrator needs to - == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/bitbucket.md'}. diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml deleted file mode 100644 index 35f7e7bb34bcfc190ca41af464136482bba56ebd..0000000000000000000000000000000000000000 --- a/app/views/projects/_commit_button.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.form-actions - .commit-button-annotation - = button_tag 'Commit Changes', - class: 'btn commit-btn js-commit-button btn-create' - = link_to 'Cancel', cancel_path, - class: 'btn btn-cancel', data: {confirm: leave_edit_message} diff --git a/app/views/projects/_dropdown.html.haml b/app/views/projects/_dropdown.html.haml deleted file mode 100644 index 3036f11bb2df15e4ace806b4da29d6d481b30ee7..0000000000000000000000000000000000000000 --- a/app/views/projects/_dropdown.html.haml +++ /dev/null @@ -1,37 +0,0 @@ -- if current_user - .dropdown.pull-right - %a.dropdown-toggle.btn.btn-new{href: '#', "data-toggle" => "dropdown"} - %i.fa.fa-bars - %ul.dropdown-menu - - if @project.issues_enabled && can?(current_user, :write_issue, @project) - %li - = link_to url_for_new_issue(@project, only_path: true), title: "New Issue" do - %i.fa.fa-fw.fa-exclamation-circle - New issue - - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project) - %li - = link_to new_namespace_project_merge_request_path(@project.namespace, @project), title: "New Merge Request" do - %i.fa.fa-fw.fa-tasks - New merge request - - if @project.snippets_enabled && can?(current_user, :write_snippet, @project) - %li - = link_to new_namespace_project_snippet_path(@project.namespace, @project), title: "New Snippet" do - %i.fa.fa-fw.fa-file-text-o - New snippet - - if can?(current_user, :admin_project_member, @project) - %li - = link_to namespace_project_project_members_path(@project.namespace, @project), title: "New project member" do - %i.fa.fa-fw.fa-users - New project member - - if can? current_user, :push_code, @project - %li.divider - %li - = link_to new_namespace_project_branch_path(@project.namespace, @project) do - %i.fa.fa-fw.fa-code-fork - New branch - %li - = link_to new_namespace_project_tag_path(@project.namespace, @project) do - %i.fa.fa-fw.fa-tag - New tag - - diff --git a/app/views/projects/_errors.html.haml b/app/views/projects/_errors.html.haml deleted file mode 100644 index 7c8bb33ed7edc4f3d868742ec68f1a16005d3aab..0000000000000000000000000000000000000000 --- a/app/views/projects/_errors.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- if @project.errors.any? - .alert.alert-danger - %button{ type: "button", class: "close", "data-dismiss" => "alert"} × - = @project.errors.full_messages.first diff --git a/app/views/projects/_github_import_modal.html.haml b/app/views/projects/_github_import_modal.html.haml deleted file mode 100644 index e88a0f7d6899263da37682cf0625f9cc8c9fa31a..0000000000000000000000000000000000000000 --- a/app/views/projects/_github_import_modal.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%div#github_import_modal.modal.hide - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3 Import projects from GitHub - .modal-body - To enable importing projects from GitHub, - - if current_user.admin? - you need to - - else - your GitLab administrator needs to - == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/github.md'}. \ No newline at end of file diff --git a/app/views/projects/_gitlab_import_modal.html.haml b/app/views/projects/_gitlab_import_modal.html.haml deleted file mode 100644 index 52212b6ae025f12132985f407da71caf2ce9936e..0000000000000000000000000000000000000000 --- a/app/views/projects/_gitlab_import_modal.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%div#gitlab_import_modal.modal.hide - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3 Import projects from GitLab.com - .modal-body - To enable importing projects from GitLab.com, - - if current_user.admin? - you need to - - else - your GitLab administrator needs to - == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/gitlab.md'}. \ No newline at end of file diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml deleted file mode 100644 index 5689bdee1c69e6b408e3ff2a622b5281a67809d0..0000000000000000000000000000000000000000 --- a/app/views/projects/_home_panel.html.haml +++ /dev/null @@ -1,43 +0,0 @@ -- empty_repo = @project.empty_repo? -.project-home-panel{:class => ("empty-project" if empty_repo)} - .project-identicon-holder - = project_icon(@project, alt: '', class: 'avatar project-avatar') - .project-home-row.project-home-row-top - .project-home-desc - - if @project.description.present? - = escaped_autolink(@project.description) - - if can?(current_user, :admin_project, @project) - – - = link_to 'Edit', edit_namespace_project_path - - elsif !@project.empty_repo? && @repository.readme - - readme = @repository.readme - – - = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@repository.root_ref, readme.name)) do - = readme.name - .project-repo-buttons - .inline.star.js-toggler-container{class: @show_star ? 'on' : ''} - - if current_user - = link_to_toggle_star('Star this project.', false) - = link_to_toggle_star('Unstar this project.', true) - - else - = link_to new_user_session_path, class: 'btn star-btn has_tooltip', title: 'You must sign in to star a project' do - %span - = icon('star') - Star - %span.count - = @project.star_count - - unless @project.empty_repo? - - if current_user && can?(current_user, :fork_project, @project) && @project.namespace != current_user.namespace - .inline.fork-buttons.prepend-left-10 - - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-sm btn-default' do - = link_to_toggle_fork - - else - = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn btn-sm btn-default' do - = link_to_toggle_fork - - .project-home-row.hidden-xs - - if current_user && !empty_repo - .project-home-dropdown - = render "dropdown" - = render "shared/clone_panel" diff --git a/app/views/projects/_issuable_form.html.haml b/app/views/projects/_issuable_form.html.haml deleted file mode 100644 index e321a84974ecf0985c17e2b24e17cdf36088ae47..0000000000000000000000000000000000000000 --- a/app/views/projects/_issuable_form.html.haml +++ /dev/null @@ -1,87 +0,0 @@ -- if issuable.errors.any? - .row - .col-sm-10.col-sm-offset-2 - .alert.alert-danger - - issuable.errors.full_messages.each do |msg| - %span= msg - %br -.form-group - = f.label :title, class: 'control-label' do - %strong= 'Title *' - .col-sm-10 - = f.text_field :title, maxlength: 255, autofocus: true, - class: 'form-control pad js-gfm-input', required: true -.form-group.issuable-description - = f.label :description, 'Description', class: 'control-label' - .col-sm-10 - - = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do - = render 'projects/zen', f: f, attr: :description, - classes: 'description form-control' - .col-sm-12.hint - .pull-left - Parsed with - #{link_to 'GitLab Flavored Markdown', help_page_path('markdown', 'markdown'), target: '_blank'}. - .pull-right - Attach files by dragging & dropping - or #{link_to 'selecting them', '#', class: 'markdown-selector' }. - - .clearfix - .error-alert -%hr -.form-group - .issue-assignee - = f.label :assignee_id, class: 'control-label' do - %i.fa.fa-user - Assign to - .col-sm-10 - = users_select_tag("#{issuable.class.model_name.param_key}[assignee_id]", - placeholder: 'Select a user', class: 'custom-form-control', null_user: true, - selected: issuable.assignee_id) -   - = link_to 'Assign to me', '#', class: 'btn assign-to-me-link' -.form-group - .issue-milestone - = f.label :milestone_id, class: 'control-label' do - %i.fa.fa-clock-o - Milestone - .col-sm-10 - - if milestone_options(issuable).present? - = f.select(:milestone_id, milestone_options(issuable), - { include_blank: 'Select milestone' }, { class: 'select2' }) - - else - .prepend-top-10 - %span.light No open milestones available. -   - - if can? current_user, :admin_milestone, issuable.project - = link_to 'Create new milestone', new_namespace_project_milestone_path(issuable.project.namespace, issuable.project), target: :blank -.form-group - = f.label :label_ids, class: 'control-label' do - %i.fa.fa-tag - Labels - .col-sm-10 - - if issuable.project.labels.any? - = f.collection_select :label_ids, issuable.project.labels.all, :id, :name, - { selected: issuable.label_ids }, multiple: true, class: 'select2' - - else - .prepend-top-10 - %span.light No labels yet. -   - - if can? current_user, :admin_label, issuable.project - = link_to 'Create new label', new_namespace_project_label_path(issuable.project.namespace, issuable.project), target: :blank - -.form-actions - - if !issuable.project.empty_repo? && (guide_url = contribution_guide_url(issuable.project)) && !issuable.persisted? - %p - Please review the - %strong #{link_to 'guidelines for contribution', guide_url} - to this repository. - - if issuable.new_record? - = f.submit "Submit new #{issuable.class.model_name.human.downcase}", class: 'btn btn-create' - - else - = f.submit 'Save changes', class: 'btn btn-save' - - if issuable.new_record? - - cancel_project = issuable.source_project - - else - - cancel_project = issuable.project - = link_to 'Cancel', [cancel_project.namespace.becomes(Namespace), cancel_project, issuable], class: 'btn btn-cancel' diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml deleted file mode 100644 index f356a25dbfa23738996debf3fca8d7c94acd4511..0000000000000000000000000000000000000000 --- a/app/views/projects/_md_preview.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%ul.nav.nav-tabs - %li.active - = link_to '#md-write-holder', class: 'js-md-write-button' do - Write - %li - = link_to '#md-preview-holder', class: 'js-md-preview-button', - data: { url: markdown_preview_namespace_project_path(@project.namespace, @project) } do - Preview -%div - .md-write-holder - = yield - .md-preview-holder.hide - .js-md-preview{class: (preview_class if defined?(preview_class))} diff --git a/app/views/projects/_settings_nav.html.haml b/app/views/projects/_settings_nav.html.haml deleted file mode 100644 index 281a84a3d3c84ddc77a0ec4a8249883eba47a64e..0000000000000000000000000000000000000000 --- a/app/views/projects/_settings_nav.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -%ul.project-settings-nav.sidebar-subnav - = nav_link(path: 'projects#edit') do - = link_to edit_project_path(@project), title: 'Project', class: "stat-tab tab " do - %i.fa.fa-pencil-square-o - %span - Project - = nav_link(controller: [:project_members, :teams]) do - = link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: "team-tab tab" do - %i.fa.fa-users - %span - Members - = nav_link(controller: :deploy_keys) do - = link_to namespace_project_deploy_keys_path(@project.namespace, @project), title: 'Deploy Keys' do - %i.fa.fa-key - %span - Deploy Keys - = nav_link(controller: :hooks) do - = link_to namespace_project_hooks_path(@project.namespace, @project), title: 'Web Hooks' do - %i.fa.fa-link - %span - Web Hooks - = nav_link(controller: :services) do - = link_to namespace_project_services_path(@project.namespace, @project), title: 'Services' do - %i.fa.fa-cogs - %span - Services - = nav_link(controller: :protected_branches) do - = link_to namespace_project_protected_branches_path(@project.namespace, @project), title: 'Protected Branches' do - %i.fa.fa-lock - %span - Protected branches diff --git a/app/views/projects/_visibility_level.html.haml b/app/views/projects/_visibility_level.html.haml deleted file mode 100644 index 42c8e685224c022894f724ce9140d50d6be4273e..0000000000000000000000000000000000000000 --- a/app/views/projects/_visibility_level.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -.form-group.project-visibility-level-holder - = f.label :visibility_level, class: 'control-label' do - Visibility Level - = link_to "(?)", help_page_path("public_access", "public_access") - .col-sm-10 - - if can_change_visibility_level - - Gitlab::VisibilityLevel.values.each do |level| - .radio - - restricted = restricted_visibility_levels.include?(level) - = label :project_visibility_level, level do - = f.radio_button :visibility_level, level, checked: (visibility_level == level), disabled: restricted - = visibility_level_icon(level) - .option-title - = visibility_level_label(level) - .option-descr - = visibility_level_description(level) - - unless restricted_visibility_levels.empty? - .col-sm-10 - %span.info - Some visibility level settings have been restricted by the administrator. - - else - .col-sm-10 - %span.info - = visibility_level_icon(visibility_level) - %strong - = visibility_level_label(visibility_level) - .light= visibility_level_description(visibility_level) diff --git a/app/views/projects/_zen.html.haml b/app/views/projects/_zen.html.haml deleted file mode 100644 index cf1c55ecca6535a3f1b6ec4a172e793dfb6c8b2a..0000000000000000000000000000000000000000 --- a/app/views/projects/_zen.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -.zennable - %input#zen-toggle-comment.zen-toggle-comment{ tabindex: '-1', type: 'checkbox' } - .zen-backdrop - - classes << ' js-gfm-input markdown-area' - = f.text_area attr, class: classes, placeholder: 'Leave a comment' - = link_to nil, class: 'zen-enter-link', tabindex: '-1' do - %i.fa.fa-expand - Edit in fullscreen - = link_to nil, class: 'zen-leave-link' do - %i.fa.fa-compress diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml deleted file mode 100644 index e6a859fea8fbe96445adf1327777199c9c570c1f..0000000000000000000000000000000000000000 --- a/app/views/projects/blame/show.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -%h3.page-title Blame view - -#tree-holder.tree-holder - .file-holder - .file-title - %i.fa.fa-file - %strong - = @path - %small= number_to_human_size @blob.size - .file-actions - = render "projects/blob/actions" - .file-content.blame.highlight - %table - - @blame.each do |commit, lines, since| - - commit = Commit.new(commit) - %tr - %td.blame-commit - %span.commit - = link_to commit.short_id, namespace_project_commit_path(@project.namespace, @project, commit), class: "commit_short_id" -   - = commit_author_link(commit, avatar: true, size: 16) -   - = link_to_gfm truncate(commit.title, length: 20), namespace_project_commit_path(@project.namespace, @project, commit.id), class: "row_title" - %td.lines.blame-numbers - %pre - - (since...(since + lines.count)).each do |i| - = i - \ - %td.lines - %pre{class: 'code highlight white'} - %code - :erb - <% lines.each do |line| %> - <%= highlight(@blob.name, line, true).html_safe %> - <% end %> diff --git a/app/views/projects/blob/_actions.html.haml b/app/views/projects/blob/_actions.html.haml deleted file mode 100644 index 13f8271b979c080a5fe28bb79c41c8aaf1cff818..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/_actions.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -.btn-group.tree-btn-group - = edit_blob_link(@project, @ref, @path) - = link_to 'Raw', namespace_project_raw_path(@project.namespace, @project, @id), - class: 'btn btn-sm', target: '_blank' - -# only show normal/blame view links for text files - - if @blob.text? - - if current_page? namespace_project_blame_path(@project.namespace, @project, @id) - = link_to 'Normal View', namespace_project_blob_path(@project.namespace, @project, @id), - class: 'btn btn-sm' - - else - = link_to 'Blame', namespace_project_blame_path(@project.namespace, @project, @id), - class: 'btn btn-sm' unless @blob.empty? - = link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), - class: 'btn btn-sm' - - if @ref != @commit.sha - = link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project, - tree_join(@commit.sha, @path)), class: 'btn btn-sm' - -- if allowed_tree_edit? - = button_tag class: 'remove-blob btn btn-sm btn-remove', - 'data-toggle' => 'modal', 'data-target' => '#modal-remove-blob' do - Remove diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml deleted file mode 100644 index 65c3ab10e0215ef997ff9740fd92fe97a0f6643d..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/_blob.html.haml +++ /dev/null @@ -1,37 +0,0 @@ -%ul.breadcrumb.repo-breadcrumb - %li - %i.fa.fa-angle-right - = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do - = @project.path - - tree_breadcrumbs(@tree, 6) do |title, path| - %li - - if path - - if path.end_with?(@path) - = link_to namespace_project_blob_path(@project.namespace, @project, path) do - %strong - = truncate(title, length: 40) - - else - = link_to truncate(title, length: 40), namespace_project_tree_path(@project.namespace, @project, path) - - else - = link_to title, '#' - -%ul.blob-commit-info.well.hidden-xs - - blob_commit = @repository.last_commit_for_path(@commit.id, blob.path) - = render blob_commit, project: @project - -%div#tree-content-holder.tree-content-holder - %article.file-holder - .file-title - = blob_icon blob.mode, blob.name - %strong - = blob.name - %small - = number_to_human_size(blob.size) - .file-actions.hidden-xs - = render "actions" - - if blob.text? - = render "text", blob: blob - - elsif blob.image? - = render "image", blob: blob - - else - = render "download", blob: blob diff --git a/app/views/projects/blob/_download.html.haml b/app/views/projects/blob/_download.html.haml deleted file mode 100644 index f2c5e95ecf4252d8612c8399d1ff2525b2e4907c..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/_download.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -.file-content.blob_file.blob-no-preview - .center - = link_to namespace_project_raw_path(@project.namespace, @project, @id) do - %h1.light - %i.fa.fa-download - %h4 - Download (#{number_to_human_size blob.size}) diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml deleted file mode 100644 index 96f188e4aa7ab644487318d53faf2a021a4053b7..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/_editor.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -.file-holder.file - .file-title - .editor-ref - %i.fa.fa-code-fork - = ref - %span.editor-file-name - - if @path - %span.monospace - = @path - - - if current_action?(:new) || current_action?(:create) - \/ - = text_field_tag 'file_name', params[:file_name], placeholder: "File name", - required: true, class: 'form-control new-file-name' - .pull-right - = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control' - - .file-content.code - %pre.js-edit-mode-pane#editor - = params[:content] || local_assigns[:blob_data] - - if local_assigns[:path] - .js-edit-mode-pane#preview.hide - .center - %h2 - %i.icon-spinner.icon-spin diff --git a/app/views/projects/blob/_image.html.haml b/app/views/projects/blob/_image.html.haml deleted file mode 100644 index c090f690d1d7d90602112e28447a736f1ea5f8f6..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/_image.html.haml +++ /dev/null @@ -1,2 +0,0 @@ -.file-content.image_file - %img{ src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"} diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml deleted file mode 100644 index 09559a4967b929b0a0a8c61754587dc6bf26c6e6..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/_remove.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -#modal-remove-blob.modal.hide - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3.page-title Remove #{@blob.name} - %p.light - From branch - %strong= @ref - - .modal-body - = form_tag namespace_project_blob_path(@project.namespace, @project, @id), method: :delete, class: 'form-horizontal' do - = render 'shared/commit_message_container', params: params, - placeholder: 'Removed this file because...' - .form-group - .col-sm-2 - .col-sm-10 - = button_tag 'Remove file', class: 'btn btn-remove btn-remove-file' - = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" - -:javascript - disableButtonIfEmptyField('#commit_message', '.btn-remove-file') diff --git a/app/views/projects/blob/_text.html.haml b/app/views/projects/blob/_text.html.haml deleted file mode 100644 index f6bd62f239baab71521db45ea9131ac41c99a4bc..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/_text.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -- if gitlab_markdown?(blob.name) - .file-content.wiki - = preserve do - = markdown(blob.data) -- elsif markup?(blob.name) - .file-content.wiki - = render_markup(blob.name, blob.data) -- else - .file-content.code - - unless blob.empty? - = render 'shared/file_highlight', blob: blob - - else - .nothing-here-block Empty file diff --git a/app/views/projects/blob/diff.html.haml b/app/views/projects/blob/diff.html.haml deleted file mode 100644 index 5c79d0ef11f75e941b165b3a18c099fb401d5352..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/diff.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -- if @lines.present? - - if @form.unfold? && @form.since != 1 && !@form.bottom? - %tr.line_holder{ id: @form.since } - = render "projects/diffs/match_line", {line: @match_line, - line_old: @form.since, line_new: @form.since, bottom: false} - - - @lines.each_with_index do |line, index| - - line_new = index + @form.since - - line_old = line_new - @form.offset - %tr.line_holder - %td.old_line.diff-line-num{data: {linenumber: line_old}} - = link_to raw(line_old), "#" - %td.new_line= link_to raw(line_new) , "#" - %td.line_content.noteable_line= line - - - if @form.unfold? && @form.bottom? && @form.to < @blob.loc - %tr.line_holder{ id: @form.to } - = render "projects/diffs/match_line", {line: @match_line, - line_old: @form.to, line_new: @form.to, bottom: true} diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml deleted file mode 100644 index 1f61a0b940c84b940e1517111b65e67180c8d889..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/edit.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -.file-editor - %ul.nav.nav-tabs.js-edit-mode - %li.active - = link_to '#editor' do - %i.fa.fa-edit - Edit file - - %li - = link_to '#preview', 'data-preview-url' => namespace_project_preview_blob_path(@project.namespace, @project, @id) do - %i.fa.fa-eye - = editing_preview_title(@blob.name) - - = form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: "form-horizontal") do - = render 'projects/blob/editor', ref: @ref, path: @path, blob_data: @blob.data - = render 'shared/commit_message_container', params: params, - placeholder: "Update #{@blob.name}" - - .form-group.branch - = label_tag 'branch', class: 'control-label' do - Branch - .col-sm-10 - = text_field_tag 'new_branch', @ref, class: "form-control" - - = hidden_field_tag 'last_commit', @last_commit - = hidden_field_tag 'content', '', id: "file-content" - = hidden_field_tag 'from_merge_request_id', params[:from_merge_request_id] - = render 'projects/commit_button', ref: @ref, - cancel_path: @after_edit_path - -:javascript - blob = new EditBlob(gon.relative_url_root + "#{Gitlab::Application.config.assets.prefix}", "#{@blob.language.try(:ace_mode)}") diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml deleted file mode 100644 index d78a01f6422ceed88b7dbdd057a297499adb1ff4..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/new.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -%h3.page-title New file -.file-editor - = form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal form-new-file') do - = render 'projects/blob/editor', ref: @ref - = render 'shared/commit_message_container', params: params, - placeholder: 'Add new file' - - .form-group.branch - = label_tag 'branch', class: 'control-label' do - Branch - .col-sm-10 - = text_field_tag 'new_branch', @ref, class: "form-control" - - = hidden_field_tag 'content', '', id: 'file-content' - = render 'projects/commit_button', ref: @ref, - cancel_path: namespace_project_tree_path(@project.namespace, @project, @id) - -:javascript - blob = new NewBlob(gon.relative_url_root + "#{Gitlab::Application.config.assets.prefix}", null) diff --git a/app/views/projects/blob/preview.html.haml b/app/views/projects/blob/preview.html.haml deleted file mode 100644 index e7c3460ad7852ec49bfe84f0e0af009ec2634bd3..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/preview.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -.diff-file - .diff-content - - if gitlab_markdown?(@blob.name) - .file-content.wiki - = preserve do - = markdown(@content) - - elsif markup?(@blob.name) - .file-content.wiki - = raw render_markup(@blob.name, @content) - - else - .file-content.code - - unless @diff_lines.empty? - %table.text-file - - @diff_lines.each do |line| - %tr.line_holder{ class: "#{line.type}" } - - if line.type == "match" - %td.old_line= "..." - %td.new_line= "..." - %td.line_content.matched= line.text - - else - %td.old_line - %td.new_line - %td.line_content{class: "#{line.type}"}= raw diff_line_content(line.text) - - else - .nothing-here-block No changes. diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml deleted file mode 100644 index 69167654c39d9fac445e6c80245c154fd1baa86f..0000000000000000000000000000000000000000 --- a/app/views/projects/blob/show.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -%div.tree-ref-holder - = render 'shared/ref_switcher', destination: 'blob', path: @path - -%div#tree-holder.tree-holder - = render 'blob', blob: @blob - -- if allowed_tree_edit? - = render 'projects/blob/remove' diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml deleted file mode 100644 index 4e7415be4aa25f417639b959b8236c4ce35a0c6c..0000000000000000000000000000000000000000 --- a/app/views/projects/branches/_branch.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -- commit = @repository.commit(branch.target) -%li(class="js-branch-#{branch.name}") - %h4 - = link_to namespace_project_tree_path(@project.namespace, @project, branch.name) do - %strong.str-truncated= branch.name - - if branch.name == @repository.root_ref - %span.label.label-info default - - if @project.protected_branch? branch.name - %span.label.label-success - %i.fa.fa-lock - protected - .pull-right - - if can?(current_user, :download_code, @project) - = render 'projects/repositories/download_archive', ref: branch.name, btn_class: 'btn-grouped btn-group-xs' - - if branch.name != @repository.root_ref - = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: branch.name), class: 'btn btn-grouped btn-xs', method: :post, title: "Compare" do - %i.fa.fa-files-o - Compare - - - if can_remove_branch?(@project, branch.name) - = link_to namespace_project_branch_path(@project.namespace, @project, branch.name), class: 'btn btn-grouped btn-xs btn-remove remove-row', method: :delete, data: { confirm: 'Removed branch cannot be restored. Are you sure?'}, remote: true do - %i.fa.fa-trash-o - - - if commit - %ul.list-unstyled - = render 'projects/commits/inline_commit', commit: commit, project: @project - - else - %p - Cant find HEAD commit for this branch diff --git a/app/views/projects/branches/destroy.js.haml b/app/views/projects/branches/destroy.js.haml deleted file mode 100644 index 882a4d0c5e26672dd1f439814e0fce7c5c23dd27..0000000000000000000000000000000000000000 --- a/app/views/projects/branches/destroy.js.haml +++ /dev/null @@ -1 +0,0 @@ -$('.js-totalbranch-count').html("#{@repository.branches.size}") diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml deleted file mode 100644 index a313ffcf27294a07dc1e6024d5c2ac2077d4f6f6..0000000000000000000000000000000000000000 --- a/app/views/projects/branches/index.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -= render "projects/commits/head" -%h3.page-title - Branches - .pull-right - - if can? current_user, :push_code, @project - = link_to new_namespace_project_branch_path(@project.namespace, @project), class: 'btn btn-create' do - %i.fa.fa-add-sign - New branch -   - .dropdown.inline - %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} - %span.light sort: - - if @sort.present? - = @sort.humanize - - else - Name - %b.caret - %ul.dropdown-menu - %li - = link_to namespace_project_branches_path(sort: nil) do - Name - = link_to namespace_project_branches_path(sort: 'recently_updated') do - = sort_title_recently_updated - = link_to namespace_project_branches_path(sort: 'last_updated') do - = sort_title_oldest_updated -%hr -- unless @branches.empty? - %ul.bordered-list.top-list.all-branches - - @branches.each do |branch| - = render "projects/branches/branch", branch: branch - = paginate @branches, theme: 'gitlab' diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml deleted file mode 100644 index e5fcb98c68cb00d8f561619a77cfea206579c100..0000000000000000000000000000000000000000 --- a/app/views/projects/branches/new.html.haml +++ /dev/null @@ -1,28 +0,0 @@ -- if @error - .alert.alert-danger - %button{ type: "button", class: "close", "data-dismiss" => "alert"} × - = @error -%h3.page-title - %i.fa.fa-code-fork - New branch -= form_tag namespace_project_branches_path, method: :post, id: "new-branch-form", class: "form-horizontal" do - .form-group - = label_tag :branch_name, 'Name for new branch', class: 'control-label' - .col-sm-10 - = text_field_tag :branch_name, params[:branch_name], placeholder: 'enter new branch name', required: true, tabindex: 1, class: 'form-control' - .form-group - = label_tag :ref, 'Create from', class: 'control-label' - .col-sm-10 - = text_field_tag :ref, params[:ref], placeholder: 'existing branch name, tag or commit SHA', required: true, tabindex: 2, class: 'form-control' - .form-actions - = button_tag 'Create branch', class: 'btn btn-create', tabindex: 3 - = link_to 'Cancel', namespace_project_branches_path(@project.namespace, @project), class: 'btn btn-cancel' - -:javascript - disableButtonIfAnyEmptyField($("#new-branch-form"), ".form-control", ".btn-create"); - var availableTags = #{@project.repository.ref_names.to_json}; - - $("#ref").autocomplete({ - source: availableTags, - minLength: 1 - }); diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml deleted file mode 100644 index 3f645b81397acc36b97a71a4d337f7b7cf564025..0000000000000000000000000000000000000000 --- a/app/views/projects/commit/_commit_box.html.haml +++ /dev/null @@ -1,52 +0,0 @@ -.pull-right - %div - - if @notes_count > 0 - %span.btn.disabled.btn-grouped - %i.fa.fa-comment - = @notes_count - .pull-left.btn-group - %a.btn.btn-grouped.dropdown-toggle{ data: {toggle: :dropdown} } - %i.fa.fa-download - Download as - %span.caret - %ul.dropdown-menu - - unless @commit.parents.length > 1 - %li= link_to "Email Patches", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch) - %li= link_to "Plain Diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff) - = link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-primary btn-grouped" do - %span Browse Code » - %div - -%p - %span.light Commit - = link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit) -.commit-info-row - %span.light Authored by - %strong - = commit_author_link(@commit, avatar: true, size: 24) - #{time_ago_with_tooltip(@commit.authored_date)} - -- if @commit.different_committer? - .commit-info-row - %span.light Committed by - %strong - = commit_committer_link(@commit, avatar: true, size: 24) - #{time_ago_with_tooltip(@commit.committed_date)} - -.commit-info-row - %span.cgray= pluralize(@commit.parents.count, "parent") - - @commit.parents.each do |parent| - = link_to parent.short_id, namespace_project_commit_path(@project.namespace, @project, parent) - -.commit-info-row.branches - %i.fa.fa-spinner.fa-spin - -.commit-box - %h3.commit-title - = gfm escape_once(@commit.title) - - if @commit.description.present? - %pre.commit-description - = preserve(gfm(escape_once(@commit.description))) - -:coffeescript - $(".commit-info-row.branches").load("#{branches_namespace_project_commit_path(@project.namespace, @project, @commit.id)}") diff --git a/app/views/projects/commit/branches.html.haml b/app/views/projects/commit/branches.html.haml deleted file mode 100644 index 82aac1fbd15e4424b7c7b7b6eeeaa8a366dd4b90..0000000000000000000000000000000000000000 --- a/app/views/projects/commit/branches.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -- if @branches.any? - %span - - branch = commit_default_branch(@project, @branches) - = link_to(namespace_project_tree_path(@project.namespace, @project, branch)) do - %span.label.label-gray - %i.fa.fa-code-fork - = branch - - if @branches.any? || @tags.any? - = link_to("#", class: "js-details-expand") do - %span.label.label-gray - \... - %span.js-details-content.hide - - if @branches.any? - = commit_branches_links(@project, @branches) - - if @tags.any? - = commit_tags_links(@project, @tags) diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml deleted file mode 100644 index fc721067ed4d870da8deec7ea2466d67c089804e..0000000000000000000000000000000000000000 --- a/app/views/projects/commit/show.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -= render "commit_box" -= render "projects/diffs/diffs", diffs: @diffs, project: @project -= render "projects/notes/notes_with_form" diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml deleted file mode 100644 index c6026f968045358927506784a4cb8bf0812f5ee4..0000000000000000000000000000000000000000 --- a/app/views/projects/commits/_commit.html.haml +++ /dev/null @@ -1,33 +0,0 @@ -%li.commit.js-toggle-container - .commit-row-title - %strong.str-truncated - = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message" - - if commit.description? - %a.text-expander.js-toggle-button ... - - .pull-right - = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" - - .notes_count - - if @note_counts - - note_count = @note_counts.fetch(commit.id, 0) - - else - - notes = project.notes.for_commit_id(commit.id) - - note_count = notes.user.count - - - if note_count > 0 - %span.light - %i.fa.fa-comments - = note_count - - - if commit.description? - .commit-row-description.js-toggle-content - %pre - = preserve(gfm(escape_once(commit.description))) - - .commit-row-info - = commit_author_link(commit, avatar: true, size: 24) - authored - .committed_ago - #{time_ago_with_tooltip(commit.committed_date)}   - = link_to_browse_code(project, commit) diff --git a/app/views/projects/commits/_commit_list.html.haml b/app/views/projects/commits/_commit_list.html.haml deleted file mode 100644 index 2ee7d73bd20950eb79eca087882a905d5b1e2540..0000000000000000000000000000000000000000 --- a/app/views/projects/commits/_commit_list.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -%div.panel.panel-default - .panel-heading - Commits (#{@commits.count}) - - if @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE - %ul.well-list - - Commit.decorate(@commits.first(MergeRequestDiff::COMMITS_SAFE_SIZE)).each do |commit| - = render "projects/commits/inline_commit", commit: commit, project: @project - %li.warning-row.unstyled - other #{@commits.size - MergeRequestDiff::COMMITS_SAFE_SIZE} commits hidden to prevent performance issues. - - else - %ul.well-list= render Commit.decorate(@commits), project: @project diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml deleted file mode 100644 index 0cd9ce1f371dc0a69705db8e9696856618634fc9..0000000000000000000000000000000000000000 --- a/app/views/projects/commits/_commits.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -- unless defined?(project) - - project = @project - -- @commits.group_by { |c| c.committed_date.to_date }.sort.reverse.each do |day, commits| - .row.commits-row - .col-md-2.hidden-xs.hidden-sm - %h5.commits-row-date - %i.fa.fa-calendar - %span= day.stamp("28 Aug, 2010") - .light - = pluralize(commits.count, 'commit') - .col-md-10.col-sm-12 - %ul.bordered-list - = render commits, project: project - %hr.lists-separator diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml deleted file mode 100644 index a714f5f79e0f602ffcfcc754bd61edf224bcfa62..0000000000000000000000000000000000000000 --- a/app/views/projects/commits/_head.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -%ul.nav.nav-tabs - = nav_link(controller: [:commit, :commits]) do - = link_to namespace_project_commits_path(@project.namespace, @project, @repository.root_ref) do - Commits - %span.badge= number_with_precision(@repository.commit_count, precision: 0, delimiter: ',') - = nav_link(controller: :compare) do - = link_to 'Compare', namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: @ref || @repository.root_ref) - - = nav_link(html_options: {class: branches_tab_class}) do - = link_to namespace_project_branches_path(@project.namespace, @project) do - Branches - %span.badge.js-totalbranch-count= @repository.branches.size - - = nav_link(controller: :tags) do - = link_to namespace_project_tags_path(@project.namespace, @project) do - Tags - %span.badge.js-totaltags-count= @repository.tags.length diff --git a/app/views/projects/commits/_inline_commit.html.haml b/app/views/projects/commits/_inline_commit.html.haml deleted file mode 100644 index c03bc3f9df9edea05d80acb1377ad88d7e363735..0000000000000000000000000000000000000000 --- a/app/views/projects/commits/_inline_commit.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -%li.commit.inline-commit - .commit-row-title - = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" -   - %span.str-truncated - = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message" - .pull-right - #{time_ago_with_tooltip(commit.committed_date)} diff --git a/app/views/projects/commits/show.atom.builder b/app/views/projects/commits/show.atom.builder deleted file mode 100644 index 9211de72b1b49bad03734dc430e09337fdf488f5..0000000000000000000000000000000000000000 --- a/app/views/projects/commits/show.atom.builder +++ /dev/null @@ -1,23 +0,0 @@ -xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do - xml.title "Recent commits to #{@project.name}:#{@ref}" - xml.link :href => namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom), :rel => "self", :type => "application/atom+xml" - xml.link :href => namespace_project_commits_url(@project.namespace, @project, @ref), :rel => "alternate", :type => "text/html" - xml.id namespace_project_commits_url(@project.namespace, @project, @ref) - xml.updated @commits.first.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") if @commits.any? - - @commits.each do |commit| - xml.entry do - xml.id namespace_project_commit_url(@project.namespace, @project, :id => commit.id) - xml.link :href => namespace_project_commit_url(@project.namespace, @project, :id => commit.id) - xml.title truncate(commit.title, :length => 80) - xml.updated commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") - xml.media :thumbnail, :width => "40", :height => "40", :url => avatar_icon(commit.author_email) - xml.author do |author| - xml.name commit.author_name - xml.email commit.author_email - end - xml.summary gfm(commit.description) - end - end -end diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml deleted file mode 100644 index 7ea855e1a4e7b863c1c14f6ba2735cf8d17f1fa0..0000000000000000000000000000000000000000 --- a/app/views/projects/commits/show.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -= render "head" - -.tree-ref-holder - = render 'shared/ref_switcher', destination: 'commits' - -- if current_user && current_user.private_token - .commits-feed-holder.hidden-xs.hidden-sm - = link_to namespace_project_commits_path(@project.namespace, @project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed", class: 'btn' do - %i.fa.fa-rss - Commits feed - -%ul.breadcrumb.repo-breadcrumb - = commits_breadcrumbs - -%div{id: dom_id(@project)} - #commits-list= render "commits", project: @project -.clear -= spinner - -- if @commits.count == @limit - :javascript - CommitsList.init("#{@ref}", #{@limit}); - diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml deleted file mode 100644 index dfb1dded9eaf70e2c12b1a425c189fb39a9f9366..0000000000000000000000000000000000000000 --- a/app/views/projects/compare/_form.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -= form_tag namespace_project_compare_index_path(@project.namespace, @project), method: :post, class: 'form-inline' do - .clearfix.append-bottom-20 - - if params[:to] && params[:from] - = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'} - .form-group - .input-group.inline-input-group - %span.input-group-addon from - = text_field_tag :from, params[:from], class: "form-control" - = "..." - .form-group - .input-group.inline-input-group - %span.input-group-addon to - = text_field_tag :to, params[:to], class: "form-control" -   - = button_tag "Compare", class: "btn btn-create commits-compare-btn" - - if compare_to_mr_button? - = link_to compare_mr_path, class: 'prepend-left-10 btn' do - %strong Make a merge request - - -:javascript - var availableTags = #{@project.repository.ref_names.to_json}; - - $("#from, #to").autocomplete({ - source: availableTags, - minLength: 1 - }); - - disableButtonIfEmptyField('#to', '.commits-compare-btn'); diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml deleted file mode 100644 index 4745bfbeaaf061e5a1f896ed2864f0ac76b2be73..0000000000000000000000000000000000000000 --- a/app/views/projects/compare/index.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -= render "projects/commits/head" - -%h3.page-title - Compare View -%p.slead - Compare branches, tags or commit ranges. - %br - Fill input field with commit id like - %code.label-branch 4eedf23 - or branch/tag name like - %code.label-branch master - and press compare button for the commits list and a code diff. - %br - Changes are shown from the version in the first field to the version in the second field. - -= render "form" diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml deleted file mode 100644 index 214b5bd337b5cb007189d1c4434f735609ad1cb6..0000000000000000000000000000000000000000 --- a/app/views/projects/compare/show.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -= render "projects/commits/head" - -%h3.page-title - Compare View - -= render "form" - -- if @commits.present? - = render "projects/commits/commit_list" - = render "projects/diffs/diffs", diffs: @diffs, project: @project -- else - .light-well - .center - %h4 - There isn't anything to compare. - %p.slead - - if params[:to] == params[:from] - %span.label-branch #{params[:from]} - and - %span.label-branch #{params[:to]} - are the same. - - else - You'll need to use different branch names to get a valid comparison. diff --git a/app/views/projects/deploy_keys/_deploy_key.html.haml b/app/views/projects/deploy_keys/_deploy_key.html.haml deleted file mode 100644 index c577dfa8d55993544975f0e602c137881e474116..0000000000000000000000000000000000000000 --- a/app/views/projects/deploy_keys/_deploy_key.html.haml +++ /dev/null @@ -1,36 +0,0 @@ -%li - .pull-right - - if @available_keys.include?(deploy_key) - = link_to enable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-sm', method: :put do - %i.fa.fa-plus - Enable - - else - - if deploy_key.destroyed_when_orphaned? && deploy_key.almost_orphaned? - = link_to 'Remove', disable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), data: { confirm: 'You are going to remove deploy key. Are you sure?'}, method: :put, class: "btn btn-remove delete-key btn-sm pull-right" - - else - = link_to disable_namespace_project_deploy_key_path(@project.namespace, @project, deploy_key), class: 'btn btn-sm', method: :put do - %i.fa.fa-power-off - Disable - - - if project = project_for_deploy_key(deploy_key) - = link_to namespace_project_deploy_key_path(project.namespace, project, deploy_key) do - %i.fa.fa-key - %strong= deploy_key.title - - else - %i.fa.fa-key - %strong= deploy_key.title - - - %p.light.prepend-top-10 - - if deploy_key.public? - %span.label.label-info.deploy-project-label - Public deploy key - - - deploy_key.projects.each do |project| - - if can?(current_user, :read_project, project) - %span.label.label-gray.deploy-project-label - = link_to namespace_project_path(project.namespace, project) do - = project.name_with_namespace - - %small.pull-right - Created #{time_ago_with_tooltip(deploy_key.created_at)} diff --git a/app/views/projects/deploy_keys/_form.html.haml b/app/views/projects/deploy_keys/_form.html.haml deleted file mode 100644 index 91675b3738ecb9f2d734c2dacd415713816ea5e9..0000000000000000000000000000000000000000 --- a/app/views/projects/deploy_keys/_form.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -%div - = form_for [@project.namespace.becomes(Namespace), @project, @key], url: namespace_project_deploy_keys_path, html: { class: 'deploy-key-form form-horizontal' } do |f| - -if @key.errors.any? - .alert.alert-danger - %ul - - @key.errors.full_messages.each do |msg| - %li= msg - - .form-group - = f.label :title, class: "control-label" - .col-sm-10= f.text_field :title, class: 'form-control' - .form-group - = f.label :key, class: "control-label" - .col-sm-10 - %p.light - Paste a machine public key here. Read more about how to generate it - = link_to "here", help_page_path("ssh", "README") - = f.text_area :key, class: "form-control thin_area", rows: 5 - - .form-actions - = f.submit 'Create', class: "btn-create btn" - = link_to "Cancel", namespace_project_deploy_keys_path(@project.namespace, @project), class: "btn btn-cancel" - diff --git a/app/views/projects/deploy_keys/index.html.haml b/app/views/projects/deploy_keys/index.html.haml deleted file mode 100644 index 472a13a85242018cecb712a20c692fd00b23125c..0000000000000000000000000000000000000000 --- a/app/views/projects/deploy_keys/index.html.haml +++ /dev/null @@ -1,41 +0,0 @@ -%h3.page-title - Deploy keys allow read-only access to the repository - - = link_to new_namespace_project_deploy_key_path(@project.namespace, @project), class: "btn btn-new pull-right", title: "New Deploy Key" do - %i.fa.fa-plus - New Deploy Key - -%p.light - Deploy keys can be used for CI, staging or production servers. - You can create a deploy key or add an existing one - -%hr.clearfix - -.row - .col-md-6.enabled-keys - %h5 - %strong.cgreen Enabled deploy keys - for this project - %ul.bordered-list - = render @enabled_keys - - if @enabled_keys.blank? - .light-well - .nothing-here-block Create a #{link_to 'new deploy key', new_namespace_project_deploy_key_path(@project.namespace, @project)} or add an existing one - .col-md-6.available-keys - - # If there are available public deploy keys but no available project deploy keys, only public deploy keys are shown. - - if @available_project_keys.any? || @available_public_keys.blank? - %h5 - %strong Deploy keys - from projects you have access to - %ul.bordered-list - = render @available_project_keys - - if @available_project_keys.blank? - .light-well - .nothing-here-block Deploy keys from projects you have access to will be displayed here - - - if @available_public_keys.any? - %h5 - %strong Public deploy keys - available to any project - %ul.bordered-list - = render @available_public_keys diff --git a/app/views/projects/deploy_keys/new.html.haml b/app/views/projects/deploy_keys/new.html.haml deleted file mode 100644 index 186d6b58972f256ea8719302eb4f109e8a3748ca..0000000000000000000000000000000000000000 --- a/app/views/projects/deploy_keys/new.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h3.page-title New Deploy key -%hr - -= render 'form' diff --git a/app/views/projects/deploy_keys/show.html.haml b/app/views/projects/deploy_keys/show.html.haml deleted file mode 100644 index 405b5bcd0d3a81e8a6f7da5c10866bafd4408b6f..0000000000000000000000000000000000000000 --- a/app/views/projects/deploy_keys/show.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%h3.page-title - Deploy key: - = @key.title - %small - created on - = @key.created_at.stamp("Aug 21, 2011") -.back-link - = link_to namespace_project_deploy_keys_path(@project.namespace, @project) do - ← To keys list -%hr -%pre= @key.key -.pull-right - = link_to 'Remove', namespace_project_deploy_key_path(@project.namespace, @project, @key), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn-remove btn delete-key" diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml deleted file mode 100644 index b49aee504fe936789a7b45d06c893a45f511dd0f..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_diffs.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -.prepend-top-20.append-bottom-20 - .pull-right - .btn-group - = inline_diff_btn - = parallel_diff_btn - = render 'projects/diffs/stats', diffs: diffs - -- if show_diff_size_warning?(diffs) - = render 'projects/diffs/warning', diffs: diffs - -.files - - safe_diff_files(diffs).each_with_index do |diff_file, index| - = render 'projects/diffs/file', diff_file: diff_file, i: index, project: project - -- if @diff_timeout - .alert.alert-danger - %h4 - Failed to collect changes - %p - Maybe diff is really big and operation failed with timeout. Try to get diff locally - -:coffeescript - $('.files .diff-header').stick_in_parent(offset_top: $('.navbar').height()) diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml deleted file mode 100644 index 672a6635321926492dd492d42d4ba73f0475c5c4..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_file.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -- blob = project.repository.blob_for_diff(@commit, diff_file.diff) -- return unless blob -- blob_diff_path = namespace_project_blob_diff_path(project.namespace, project, tree_join(@commit.id, diff_file.file_path)) -.diff-file{id: "diff-#{i}", data: {blob_diff_path: blob_diff_path }} - .diff-header{id: "file-path-#{hexdigest(diff_file.new_path || diff_file.old_path)}"} - - if diff_file.deleted_file - %span="#{diff_file.old_path} deleted" - - .diff-btn-group - - if @commit.parent_ids.present? - = view_file_btn(@commit.parent_id, diff_file, project) - - elsif diff_file.diff.submodule? - - submodule_item = project.repository.blob_at(@commit.id, diff_file.file_path) - = submodule_link(submodule_item, @commit.id) - - else - %span - - if diff_file.renamed_file - = "#{diff_file.old_path} renamed to #{diff_file.new_path}" - - else - = diff_file.new_path - - if diff_file.mode_changed? - %span.file-mode= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}" - - .diff-btn-group - - if blob.text? - = link_to '#', class: 'js-toggle-diff-comments btn btn-sm active has_tooltip', title: "Toggle comments for this file" do - %i.fa.fa-comments -   - - - if @merge_request && @merge_request.source_project - = edit_blob_link(@merge_request.source_project, - @merge_request.source_branch, diff_file.new_path, - after: ' ', from_merge_request_id: @merge_request.id) - - = view_file_btn(@commit.id, diff_file, project) - - .diff-content.diff-wrap-lines - -# Skipp all non non-supported blobs - - return unless blob.respond_to?('text?') - - if blob.text? - - if params[:view] == 'parallel' - = render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob, index: i - - else - = render "projects/diffs/text_file", diff_file: diff_file, index: i - - elsif blob.image? - - old_file = project.repository.prev_blob_for_diff(@commit, diff_file) - = render "projects/diffs/image", diff_file: diff_file, old_file: old_file, file: blob, index: i - - else - .nothing-here-block No preview for this file type - diff --git a/app/views/projects/diffs/_image.html.haml b/app/views/projects/diffs/_image.html.haml deleted file mode 100644 index 058b71b21f5173efd9c37bd02377dd691d5e7af4..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_image.html.haml +++ /dev/null @@ -1,64 +0,0 @@ -- diff = diff_file.diff -- if diff.renamed_file || diff.new_file || diff.deleted_file - .image - %span.wrap - .frame{class: image_diff_class(diff)} - %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - %p.image-info= "#{number_to_human_size file.size}" -- else - .image - %div.two-up.view - %span.wrap - .frame.deleted - %a{href: namespace_project_blob_path(@project.namespace, @project, tree_join(@commit.parent_id, diff.old_path))} - %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} - %p.image-info.hide - %span.meta-filesize= "#{number_to_human_size old_file.size}" - | - %b W: - %span.meta-width - | - %b H: - %span.meta-height - %span.wrap - .frame.added - %a{href: namespace_project_blob_path(@project.namespace, @project, tree_join(@commit.id, diff.new_path))} - %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - %p.image-info.hide - %span.meta-filesize= "#{number_to_human_size file.size}" - | - %b W: - %span.meta-width - | - %b H: - %span.meta-height - - %div.swipe.view.hide - .swipe-frame - .frame.deleted - %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} - .swipe-wrap - .frame.added - %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - %span.swipe-bar - %span.top-handle - %span.bottom-handle - - %div.onion-skin.view.hide - .onion-skin-frame - .frame.deleted - %img{src: "data:#{old_file.mime_type};base64,#{Base64.encode64(old_file.data)}"} - .frame.added - %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - .controls - .transparent - .drag-track - .dragger{:style => "left: 0px;"} - .opaque - - - .view-modes.hide - %ul.view-modes-menu - %li.two-up{data: {mode: 'two-up'}} 2-up - %li.swipe{data: {mode: 'swipe'}} Swipe - %li.onion-skin{data: {mode: 'onion-skin'}} Onion skin diff --git a/app/views/projects/diffs/_match_line.html.haml b/app/views/projects/diffs/_match_line.html.haml deleted file mode 100644 index 4ebe3379733feaaa9fd6bbab6f0c21aa370f0058..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_match_line.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%td.old_line.diff-line-num.unfold.js-unfold{data: {linenumber: line_old}, - class: unfold_bottom_class(bottom)} - \... -%td.new_line.diff-line-num.unfold.js-unfold{data: {linenumber: line_new}, - class: unfold_bottom_class(bottom)} - \... -%td.line_content.matched= line diff --git a/app/views/projects/diffs/_match_line_parallel.html.haml b/app/views/projects/diffs/_match_line_parallel.html.haml deleted file mode 100644 index 815df16aa4ab92ed646ae99df498d78fed75a5b0..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_match_line_parallel.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%td.old_line - %td.line_content.parallel.matched= line -%td.new_line - %td.line_content.parallel.matched= line diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml deleted file mode 100644 index 75f3a80f0d7f03be10d9a0a3e5fdf0f53aab4ab6..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_parallel_view.html.haml +++ /dev/null @@ -1,41 +0,0 @@ -/ Side-by-side diff view -%div.text-file.diff-wrap-lines - %table - - parallel_diff(diff_file, index).each do |line| - - type_left = line[0] - - line_number_left = line[1] - - line_content_left = line[2] - - line_code_left = line[3] - - type_right = line[4] - - line_number_right = line[5] - - line_content_right = line[6] - - line_code_right = line[7] - - %tr.line_holder.parallel - - if type_left == 'match' - = render "projects/diffs/match_line_parallel", { line: line_content_left, - line_old: line_number_left, line_new: line_number_right } - - elsif type_left == 'old' || type_left.nil? - %td.old_line{id: line_code_left, class: "#{type_left}"} - = link_to raw(line_number_left), "##{line_code_left}", id: line_code_left - %td.line_content{class: "parallel noteable_line #{type_left} #{line_code_left}", "line_code" => line_code_left }= raw line_content_left - - - if type_right == 'new' - - new_line_class = 'new' - - new_line_code = line_code_right - - else - - new_line_class = nil - - new_line_code = line_code_left - - %td.new_line{id: new_line_code, class: "#{new_line_class}", data: { linenumber: line_number_right }} - = link_to raw(line_number_right), "##{new_line_code}", id: new_line_code - %td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", "line_code" => new_line_code}= raw line_content_right - - - if @reply_allowed - - comments_left, comments_right = organize_comments(type_left, type_right, line_code_left, line_code_right) - - if comments_left.present? || comments_right.present? - = render "projects/notes/diff_notes_with_reply_parallel", notes1: comments_left, notes2: comments_right - -- if diff_file.diff.diff.blank? && diff_file.mode_changed? - .file-mode-changed - File mode changed diff --git a/app/views/projects/diffs/_stats.html.haml b/app/views/projects/diffs/_stats.html.haml deleted file mode 100644 index 1625930615a000c8048f40278017fa5d9c1b0520..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_stats.html.haml +++ /dev/null @@ -1,38 +0,0 @@ -.js-toggle-container - .commit-stat-summary - Showing - = link_to '#', class: 'js-toggle-button' do - %strong #{pluralize(diffs.count, "changed file")} - - if current_controller?(:commit) - - unless @commit.has_zero_stats? - with - %strong.cgreen #{@commit.stats.additions} additions - and - %strong.cred #{@commit.stats.deletions} deletions - .file-stats.js-toggle-content.hide - %ul.bordered-list - - diffs.each_with_index do |diff, i| - %li - - if diff.deleted_file - %span.deleted-file - %a{href: "#diff-#{i}"} - %i.fa.fa-minus - = diff.old_path - - elsif diff.renamed_file - %span.renamed-file - %a{href: "#diff-#{i}"} - %i.fa.fa-minus - = diff.old_path - → - = diff.new_path - - elsif diff.new_file - %span.new-file - %a{href: "#diff-#{i}"} - %i.fa.fa-plus - = diff.new_path - - else - %span.edit-file - %a{href: "#diff-#{i}"} - %i.fa.fa-adjust - = diff.new_path - diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml deleted file mode 100644 index e6dfbfd651120b1ac2e3a653eb0de26324b40dc3..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_text_file.html.haml +++ /dev/null @@ -1,36 +0,0 @@ -- too_big = diff_file.diff_lines.count > Commit::DIFF_SAFE_LINES -- if too_big - %a.supp_diff_link Changes suppressed. Click to show - -%table.text-file{class: "#{'hide' if too_big}"} - - last_line = 0 - - diff_file.diff_lines.each_with_index do |line, index| - - type = line.type - - last_line = line.new_pos - - line_code = generate_line_code(diff_file.file_path, line) - - line_old = line.old_pos - %tr.line_holder{ id: line_code, class: "#{type}" } - - if type == "match" - = render "projects/diffs/match_line", {line: line.text, - line_old: line_old, line_new: line.new_pos, bottom: false} - - else - %td.old_line - = link_to raw(type == "new" ? " " : line_old), "##{line_code}", id: line_code - - if @comments_allowed && can?(current_user, :write_note, @project) - = link_to_new_diff_note(line_code) - %td.new_line{data: {linenumber: line.new_pos}} - = link_to raw(type == "old" ? " " : line.new_pos) , "##{line_code}", id: line_code - %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text) - - - if @reply_allowed - - comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at) - - unless comments.empty? - = render "projects/notes/diff_notes_with_reply", notes: comments, line: line.text - - - if last_line > 0 - = render "projects/diffs/match_line", {line: "", - line_old: last_line, line_new: last_line, bottom: true} - -- if diff_file.diff.blank? && diff_file.mode_changed? - .file-mode-changed - File mode changed diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml deleted file mode 100644 index 47abbba2eb225940bdb849e2ce7605750089aa31..0000000000000000000000000000000000000000 --- a/app/views/projects/diffs/_warning.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -.alert.alert-warning - %h4 - Too many changes. - .pull-right - - unless diff_hard_limit_enabled? - = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true)), class: "btn btn-sm btn-warning" - - - if current_controller?(:commit) or current_controller?(:merge_requests) - - if current_controller?(:commit) - = link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-warning btn-sm" - = link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-warning btn-sm" - - elsif @merge_request && @merge_request.persisted? - = link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-warning btn-sm" - = link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-warning btn-sm" - %p - To preserve performance only - %strong #{allowed_diff_size} of #{diffs.size} - files are displayed. - diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml deleted file mode 100644 index fbf04847e489f9ec8dcdcb5ffc3c1d0f7736aed5..0000000000000000000000000000000000000000 --- a/app/views/projects/edit.html.haml +++ /dev/null @@ -1,206 +0,0 @@ -.project-edit-container - .project-edit-errors - .project-edit-content - %div - %h3.page-title - Project settings - %hr - .panel-body - = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal" }, authenticity_token: true do |f| - - %fieldset - .form-group.project_name_holder - = f.label :name, class: 'control-label' do - Project name - .col-sm-10 - = f.text_field :name, placeholder: "Example Project", class: "form-control", id: "project_name_edit" - - - .form-group - = f.label :description, class: 'control-label' do - Project description - %span.light (optional) - .col-sm-10 - = f.text_area :description, placeholder: "Awesome project", class: "form-control", rows: 3, maxlength: 250 - - - if @project.repository.exists? && @project.repository.branch_names.any? - .form-group - = f.label :default_branch, "Default Branch", class: 'control-label' - .col-sm-10= f.select(:default_branch, @repository.branch_names, {}, {class: 'select2 select-wide'}) - - - = render "visibility_level", f: f, visibility_level: @project.visibility_level, can_change_visibility_level: can?(current_user, :change_visibility_level, @project) - - .form-group - = f.label :tag_list, "Tags", class: 'control-label' - .col-sm-10 - = f.text_field :tag_list, maxlength: 2000, class: "form-control" - %p.help-block Separate tags with commas. - - %fieldset.features - %legend - Features: - .form-group - = f.label :issues_enabled, "Issues", class: 'control-label' - .col-sm-10 - .checkbox - = f.check_box :issues_enabled - %span.descr Lightweight issue tracking system for this project - - .form-group - = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' - .col-sm-10 - .checkbox - = f.check_box :merge_requests_enabled - %span.descr Submit changes to be merged upstream. - - .form-group - = f.label :wiki_enabled, "Wiki", class: 'control-label' - .col-sm-10 - .checkbox - = f.check_box :wiki_enabled - %span.descr Pages for project documentation - - .form-group - = f.label :snippets_enabled, "Snippets", class: 'control-label' - .col-sm-10 - .checkbox - = f.check_box :snippets_enabled - %span.descr Share code pastes with others out of git repository - - %fieldset.features - %legend - Project avatar: - .form-group - .col-sm-2 - .col-sm-10 - - if @project.avatar? - = project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160') - %p.light - - if @project.avatar_in_git - Project avatar in repository: #{ @project.avatar_in_git } - %p.light - - if @project.avatar? - You can change your project avatar here - - else - You can upload a project avatar here - %a.choose-btn.btn.btn-sm.js-choose-project-avatar-button - %i.icon-paper-clip - %span Choose File ... -   - %span.file_name.js-avatar-filename File name... - = f.file_field :avatar, class: "js-project-avatar-input hidden" - .light The maximum file size allowed is 200KB. - - if @project.avatar? - %hr - = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" - - .form-actions - = f.submit 'Save changes', class: "btn btn-save" - - - - .danger-settings - - if can? current_user, :archive_project, @project - - if @project.archived? - .panel.panel-success - .panel-heading - Unarchive project - .panel-body - %p - Unarchiving the project will mark its repository as active. - %br - The project can be committed to. - %br - %strong Once active this project shows up in the search and on the dashboard. - = link_to 'Unarchive', unarchive_namespace_project_path(@project.namespace, @project), - data: { confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be committed to again." }, - method: :post, class: "btn btn-success" - - else - .panel.panel-warning - .panel-heading - Archive project - .panel-body - %p - Archiving the project will mark its repository as read-only. - %br - It is hidden from the dashboard and doesn't show up in searches. - %br - %strong Archived projects cannot be committed to! - = link_to 'Archive', archive_namespace_project_path(@project.namespace, @project), - data: { confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to." }, - method: :post, class: "btn btn-warning" - - else - .nothing-here-block Only the project owner can archive a project - - .panel.panel-default.panel.panel-warning - .panel-heading Rename repository - .errors-holder - .panel-body - = form_for([@project.namespace.becomes(Namespace), @project], html: { class: 'form-horizontal' }) do |f| - .form-group.project_name_holder - = f.label :name, class: 'control-label' do - Project name - .col-sm-9 - .form-group - = f.text_field :name, placeholder: "Example Project", class: "form-control" - .form-group - = f.label :path, class: 'control-label' do - %span Path - .col-sm-9 - .form-group - .input-group - .input-group-addon - #{URI.join(root_url, @project.namespace.path)}/ - = f.text_field :path, class: 'form-control' - %span.input-group-addon .git - %ul - %li Be careful. Renaming a project's repository can have unintended side effects. - %li You will need to update your local repositories to point to the new location. - .form-actions - = f.submit 'Rename', class: "btn btn-warning" - - - if can?(current_user, :change_namespace, @project) - .panel.panel-default.panel.panel-danger - .panel-heading Transfer project - .errors-holder - .panel-body - = form_for([@project.namespace.becomes(Namespace), @project], url: transfer_namespace_project_path(@project.namespace, @project), method: :put, remote: true, html: { class: 'transfer-project form-horizontal' }) do |f| - .form-group - = label_tag :new_namespace_id, nil, class: 'control-label' do - %span Namespace - .col-sm-10 - .form-group - = select_tag :new_namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace', class: 'select2' } - %ul - %li Be careful. Changing the project's namespace can have unintended side effects. - %li You can only transfer the project to namespaces you manage. - %li You will need to update your local repositories to point to the new location. - .form-actions - = f.submit 'Transfer', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => transfer_project_message(@project) } - - else - .nothing-here-block Only the project owner can transfer a project - - - if can?(current_user, :remove_project, @project) - .panel.panel-default.panel.panel-danger - .panel-heading Remove project - .panel-body - = form_tag(namespace_project_path(@project.namespace, @project), method: :delete, html: { class: 'form-horizontal'}) do - %p - Removing the project will delete its repository and all related resources including issues, merge requests etc. - %br - %strong Removed projects cannot be restored! - - = link_to 'Remove project', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_project_message(@project) } - - else - .nothing-here-block Only project owner can remove a project - -.save-project-loader.hide - .center - %h2 - %i.fa.fa-spinner.fa-spin - Saving project. - %p Please wait a moment, this page will automatically refresh when ready. - - -= render 'shared/confirm_modal', phrase: @project.path diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml deleted file mode 100644 index 49806ceaa9671182f21785534680362dac537c28..0000000000000000000000000000000000000000 --- a/app/views/projects/empty.html.haml +++ /dev/null @@ -1,49 +0,0 @@ -- if current_user && can?(current_user, :download_code, @project) - = render 'shared/no_ssh' - = render 'shared/no_password' - -= render "home_panel" - -.center.well - %h3 - The repository for this project is empty - %h4 - You can - = link_to namespace_project_new_blob_path(@project.namespace, @project, 'master'), class: 'btn btn-new btn-lg' do - add a file -  or do a push via the command line. - -%h4 - %strong Command line instructions -%div.git-empty - %fieldset - %legend Git global setup - %pre.dark - :preserve - git config --global user.name "#{git_user_name}" - git config --global user.email "#{git_user_email}" - - %fieldset - %legend Create a new repository - %pre.dark - :preserve - mkdir #{@project.path} - cd #{@project.path} - git init - touch README.md - git add README.md - git commit -m "first commit" - git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')} - git push -u origin master - - %fieldset - %legend Push an existing Git repository - %pre.dark - :preserve - cd existing_git_repo - git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'clone')} - git push -u origin master - -- if can? current_user, :remove_project, @project - .prepend-top-20 - = link_to 'Remove project', [@project.namespace.becomes(Namespace), @project], data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right" diff --git a/app/views/projects/forks/error.html.haml b/app/views/projects/forks/error.html.haml deleted file mode 100644 index 8eb4f795971939d0d5717b5e489e83593ea41a84..0000000000000000000000000000000000000000 --- a/app/views/projects/forks/error.html.haml +++ /dev/null @@ -1,20 +0,0 @@ -- if @forked_project && !@forked_project.saved? - .alert.alert-danger.alert-block - %h4 - %i.fa.fa-code-fork - Fork Error! - %p - You tried to fork - = link_to_project @project - but it failed for the following reason: - - - - if @forked_project && @forked_project.errors.any? - %p - – - = @forked_project.errors.full_messages.first - - %p - = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork", class: "btn" do - %i.fa.fa-code-fork - Try to Fork again diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml deleted file mode 100644 index 5a6c46f320885bd11a5d489780f52cc702450756..0000000000000000000000000000000000000000 --- a/app/views/projects/forks/new.html.haml +++ /dev/null @@ -1,39 +0,0 @@ -%h3.page-title Fork project -%p.lead - Click to fork the project to a user or group -%hr - -.fork-namespaces - - @namespaces.in_groups_of(6, false) do |group| - .row - - group.each do |namespace| - .col-md-2.col-sm-3 - - if fork = namespace.find_fork_of(@project) - .thumbnail.fork-exists-thumbnail - = link_to project_path(fork), title: "Visit project fork", class: 'has_tooltip' do - = image_tag namespace_icon(namespace, 200) - .caption - %h4=namespace.human_name - %p - = namespace.path - - else - .thumbnail.fork-thumbnail - = link_to namespace_project_fork_path(@project.namespace, @project, namespace_key: namespace.id), title: "Fork here", method: "POST", class: 'has_tooltip' do - = image_tag namespace_icon(namespace, 200) - .caption - %h4=namespace.human_name - %p - = namespace.path - - %p.light - Fork is a copy of a project repository. - %br - Forking a repository allows you to do changes without affecting the original project. - -.save-project-loader.hide - .center - %h2 - %i.fa.fa-spinner.fa-spin - Forking repository - %p Please wait a moment, this page will automatically refresh when ready. - diff --git a/app/views/projects/go_import.html.haml b/app/views/projects/go_import.html.haml deleted file mode 100644 index 87ac75a350fd7359245eaaf0f463207845078c71..0000000000000000000000000000000000000000 --- a/app/views/projects/go_import.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -!!! 5 -%html - %head - - web_url = [Gitlab.config.gitlab.url, @namespace, @id].join('/') - %meta{name: "go-import", content: "#{web_url.split('://')[1]} git #{web_url}.git"} diff --git a/app/views/projects/graphs/_head.html.haml b/app/views/projects/graphs/_head.html.haml deleted file mode 100644 index 9383df133058ef37fe6849cf6e5a373971a1f52d..0000000000000000000000000000000000000000 --- a/app/views/projects/graphs/_head.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -%ul.nav.nav-tabs - = nav_link(action: :show) do - = link_to 'Contributors', namespace_project_graph_path - = nav_link(action: :commits) do - = link_to 'Commits', commits_namespace_project_graph_path diff --git a/app/views/projects/graphs/commits.html.haml b/app/views/projects/graphs/commits.html.haml deleted file mode 100644 index 78b4c1923dd4669f09be01b43727a22ef01c8e69..0000000000000000000000000000000000000000 --- a/app/views/projects/graphs/commits.html.haml +++ /dev/null @@ -1,85 +0,0 @@ -= render 'head' - -%p.lead - Commit statistics for - %strong #{@repository.root_ref} - #{@commits_graph.start_date.strftime('%b %d')} - #{@commits_graph.end_date.strftime('%b %d')} - -.row - .col-md-6 - %ul - %li - %p.lead - %strong #{@commits_graph.commits.size} - commits during - %strong #{@commits_graph.duration} - days - %li - %p.lead - Average - %strong #{@commits_graph.commit_per_day} - commits per day - %li - %p.lead - Contributed by - %strong #{@commits_graph.authors} - authors - .col-md-6 - %div - %p.slead - Commits per day of month - %canvas#month-chart{width: 800, height: 400} -.row - .col-md-6 - %div - %p.slead - Commits per day hour (UTC) - %canvas#hour-chart{width: 800, height: 400} - .col-md-6 - %div - %p.slead - Commits per weekday - %canvas#weekday-chart{width: 800, height: 400} - -:coffeescript - data = { - labels : #{@commits_per_time.keys.to_json}, - datasets : [{ - fillColor : "rgba(220,220,220,0.5)", - strokeColor : "rgba(220,220,220,1)", - pointColor : "rgba(220,220,220,1)", - pointStrokeColor : "#EEE", - data : #{@commits_per_time.values.to_json} - }] - } - - ctx = $("#hour-chart").get(0).getContext("2d"); - new Chart(ctx).Line(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2}) - - data = { - labels : #{@commits_per_week_days.keys.to_json}, - datasets : [{ - fillColor : "rgba(220,220,220,0.5)", - strokeColor : "rgba(220,220,220,1)", - pointColor : "rgba(220,220,220,1)", - pointStrokeColor : "#EEE", - data : #{@commits_per_week_days.values.to_json} - }] - } - - ctx = $("#weekday-chart").get(0).getContext("2d"); - new Chart(ctx).Line(data,{"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2}) - - data = { - labels : #{@commits_per_month.keys.to_json}, - datasets : [{ - fillColor : "rgba(220,220,220,0.5)", - strokeColor : "rgba(220,220,220,1)", - pointColor : "rgba(220,220,220,1)", - pointStrokeColor : "#EEE", - data : #{@commits_per_month.values.to_json} - }] - } - - ctx = $("#month-chart").get(0).getContext("2d"); - new Chart(ctx).Line(data, {"scaleOverlay": true, responsive: true, pointHitDetectionRadius: 2}) diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml deleted file mode 100644 index e3d5094ddc5fb6bf41774a02741bfdf80de69f14..0000000000000000000000000000000000000000 --- a/app/views/projects/graphs/show.html.haml +++ /dev/null @@ -1,37 +0,0 @@ -= render 'head' -.loading-graph - .center - %h3.page-title - %i.fa.fa-spinner.fa-spin - Building repository graph. - %p.slead Please wait a moment, this page will automatically refresh when ready. - -.stat-graph.hide - .header.clearfix - %h3#date_header.page-title - %p.light - Commits to #{@project.default_branch}, excluding merge commits. Limited by 6,000 commits - %input#brush_change{:type => "hidden"} - .graphs - #contributors-master - #contributors.clearfix - %ol.contributors-list.clearfix - - - -:coffeescript - $.ajax - type: "GET", - url: location.href, - success: (data) -> - graph = new ContributorsStatGraph() - graph.init(data) - - $("#brush_change").change -> - graph.change_date_header() - graph.redraw_authors() - - $(".stat-graph").fadeIn(); - $(".loading-graph").hide(); - dataType: "json" - diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml deleted file mode 100644 index bbaddba31b9ee4bc0a2094317fa4cf8bf701e24e..0000000000000000000000000000000000000000 --- a/app/views/projects/hooks/index.html.haml +++ /dev/null @@ -1,68 +0,0 @@ -%h3.page-title - Web hooks - -%p.light - #{link_to "Web hooks ", help_page_path("web_hooks", "web_hooks"), class: "vlink"} can be - used for binding events when something is happening within the project. - -%hr.clearfix - -= form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: namespace_project_hooks_path(@project.namespace, @project), html: { class: 'form-horizontal' } do |f| - -if @hook.errors.any? - .alert.alert-danger - - @hook.errors.full_messages.each do |msg| - %p= msg - .form-group - = f.label :url, "URL", class: 'control-label' - .col-sm-10 - = f.text_field :url, class: "form-control", placeholder: 'http://example.com/trigger-ci.json' - .form-group - = f.label :url, "Trigger", class: 'control-label' - .col-sm-10 - %div - = f.check_box :push_events, class: 'pull-left' - .prepend-left-20 - = f.label :push_events, class: 'list-label' do - %strong Push events - %p.light - This url will be triggered by a push to the repository - %div - = f.check_box :tag_push_events, class: 'pull-left' - .prepend-left-20 - = f.label :tag_push_events, class: 'list-label' do - %strong Tag push events - %p.light - This url will be triggered when a new tag is pushed to the repository - %div - = f.check_box :issues_events, class: 'pull-left' - .prepend-left-20 - = f.label :issues_events, class: 'list-label' do - %strong Issues events - %p.light - This url will be triggered when an issue is created - %div - = f.check_box :merge_requests_events, class: 'pull-left' - .prepend-left-20 - = f.label :merge_requests_events, class: 'list-label' do - %strong Merge Request events - %p.light - This url will be triggered when a merge request is created - .form-actions - = f.submit "Add Web Hook", class: "btn btn-create" - --if @hooks.any? - .panel.panel-default - .panel-heading - Web hooks (#{@hooks.count}) - %ul.well-list - - @hooks.each do |hook| - %li - .pull-right - = link_to 'Test Hook', test_namespace_project_hook_path(@project.namespace, @project, hook), class: "btn btn-sm btn-grouped" - = link_to 'Remove', namespace_project_hook_path(@project.namespace, @project, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-sm btn-grouped" - .clearfix - %span.monospace= hook.url - %p - - %w(push_events tag_push_events issues_events merge_requests_events).each do |trigger| - - if hook.send(trigger) - %span.label.label-gray= trigger.titleize diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml deleted file mode 100644 index 934b6b8c017212afeb9664e0c5d7ea931463ba1b..0000000000000000000000000000000000000000 --- a/app/views/projects/imports/new.html.haml +++ /dev/null @@ -1,21 +0,0 @@ -%h3.page-title - - if @project.import_failed? - Import failed. Retry? - - else - Import repository - -%hr - -= form_for @project, url: namespace_project_import_path(@project.namespace, @project), method: :post, html: { class: 'form-horizontal' } do |f| - .form-group.import-url-data - = f.label :import_url, class: 'control-label' do - %span Import existing git repo - .col-sm-10 - = f.text_field :import_url, class: 'form-control', placeholder: 'https://github.com/randx/six.git' - .well.prepend-top-20 - This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git. - %br - The import will time out after 4 minutes. For big repositories, use a clone/push combination. - For SVN repositories, check #{link_to "this migrating from SVN doc.", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"} - .form-actions - = f.submit 'Start import', class: "btn btn-create", tabindex: 4 diff --git a/app/views/projects/imports/show.html.haml b/app/views/projects/imports/show.html.haml deleted file mode 100644 index 2d1fdafed24d31497feb9ac9dede513d38c9fbdf..0000000000000000000000000000000000000000 --- a/app/views/projects/imports/show.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -.save-project-loader - .center - %h2 - %i.fa.fa-spinner.fa-spin - Import in progress. - %p.monospace git clone --bare #{hidden_pass_url(@project.import_url)} - %p Please wait while we import the repository for you. Refresh at will. - :javascript - new ProjectImport(); diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml deleted file mode 100644 index 288b48f45834dd790c4591d86e82a31e66c01ab9..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/_discussion.html.haml +++ /dev/null @@ -1,33 +0,0 @@ -- content_for :note_actions do - - if can?(current_user, :modify_issue, @issue) - - if @issue.closed? - = link_to 'Reopen Issue', issue_path(@issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen js-note-target-reopen", title: 'Reopen Issue' - - else - = link_to 'Close Issue', issue_path(@issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close js-note-target-close", title: "Close Issue" -.row - %section.col-md-9 - .votes-holder.pull-right - #votes= render 'votes/votes_block', votable: @issue - .participants - %span= pluralize(@issue.participants(current_user).count, 'participant') - - @issue.participants(current_user).each do |participant| - = link_to_member(@project, participant, name: false, size: 24) - .voting_notes#notes= render "projects/notes/notes_with_form" - %aside.col-md-3 - .issuable-affix - .clearfix - %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} - = cross_project_reference(@project, @issue) - %hr - .context - = render partial: 'issue_context', locals: { issue: @issue } - - - if @issue.labels.any? - .issuable-context-title - %label Labels - .issue-show-labels - - @issue.labels.each do |label| - = link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do - = render_colored_label(label) - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml deleted file mode 100644 index 7d7217eb2a81f4804a40a17a62f49775b39faa97..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/_form.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -%div.issue-form-holder - %h3.page-title= @issue.new_record? ? "Create Issue" : "Edit Issue ##{@issue.iid}" - %hr - - = form_for [@project.namespace.becomes(Namespace), @project, @issue], html: { class: 'form-horizontal issue-form gfm-form' } do |f| - = render 'projects/issuable_form', f: f, issuable: @issue - -:javascript - $('.assign-to-me-link').on('click', function(e){ - $('#issue_assignee_id').val("#{current_user.id}").trigger("change"); - e.preventDefault(); - }); - - window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}"; diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml deleted file mode 100644 index 998e74d12cf8539b7fd7a5e9597da79de5c04cb5..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/_issue.html.haml +++ /dev/null @@ -1,52 +0,0 @@ -%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue) } - - if controller.controller_name == 'issues' - .issue-check - = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue", disabled: !can?(current_user, :modify_issue, issue) - - .issue-title - %span.str-truncated - = link_to_gfm issue.title, issue_path(issue), class: "row_title" - .pull-right.light - - if issue.closed? - %span - CLOSED - - note_count = issue.notes.user.count - - if note_count > 0 -   - %span - %i.fa.fa-comments - = note_count - - .issue-info - = link_to "##{issue.iid}", issue_path(issue), class: "light" - - if issue.assignee - assigned to #{link_to_member(@project, issue.assignee)} - - if issue.votes_count > 0 - = render 'votes/votes_inline', votable: issue - - if issue.milestone - %span - %i.fa.fa-clock-o - = issue.milestone.title - - if issue.tasks? - %span.task-status - = issue.task_status - - .pull-right.issue-updated-at - %small updated #{time_ago_with_tooltip(issue.updated_at, 'bottom', 'issue_update_ago')} - - .issue-labels - - issue.labels.each do |label| - = link_to namespace_project_issues_path(issue.project.namespace, issue.project, label_name: label.name) do - = render_colored_label(label) - - .issue-actions - - if can? current_user, :modify_issue, issue - - if issue.closed? - = link_to 'Reopen', issue_path(issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-sm btn-grouped reopen_issue btn-reopen", remote: true - - else - = link_to 'Close', issue_path(issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-sm btn-grouped close_issue btn-close", remote: true - = link_to edit_namespace_project_issue_path(issue.project.namespace, issue.project, issue), class: "btn btn-sm edit-issue-link btn-grouped" do - %i.fa.fa-pencil-square-o - Edit - - diff --git a/app/views/projects/issues/_issue_context.html.haml b/app/views/projects/issues/_issue_context.html.haml deleted file mode 100644 index 9228074d833a293b9fbc63df4e4f209be8c2c343..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/_issue_context.html.haml +++ /dev/null @@ -1,46 +0,0 @@ -= form_for [@project.namespace.becomes(Namespace), @project, @issue], remote: true, html: {class: 'edit-issue inline-update'} do |f| - %div.prepend-top-20 - .issuable-context-title - %label - Assignee: - - if issue.assignee - %strong= link_to_member(@project, @issue.assignee, size: 24) - - else - none - - if can?(current_user, :modify_issue, @issue) - = users_select_tag('issue[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @issue.assignee_id, null_user: true, first_user: true) - - %div.prepend-top-20.clearfix - .issuable-context-title - %label - Milestone: - - if issue.milestone - %span.back-to-milestone - = link_to namespace_project_milestone_path(@project.namespace, @project, @issue.milestone) do - %strong - %i.fa.fa-clock-o - = @issue.milestone.title - - else - none - - if can?(current_user, :modify_issue, @issue) - = f.select(:milestone_id, milestone_options(@issue), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'}) - = hidden_field_tag :issue_context - = f.submit class: 'btn' - - - if current_user - %div.prepend-top-20.clearfix - .issuable-context-title - %label - Subscription: - %button.btn.btn-block.subscribe-button - %i.fa.fa-eye - %span= @issue.subscribed?(current_user) ? "Unsubscribe" : "Subscribe" - - subscribtion_status = @issue.subscribed?(current_user) ? "subscribed" : "unsubscribed" - .subscription-status{"data-status" => subscribtion_status} - .description-block.unsubscribed{class: ( "hidden" if @issue.subscribed?(current_user) )} - You're not receiving notifications from this thread. - .description-block.subscribed{class: ( "hidden" unless @issue.subscribed?(current_user) )} - You're receiving notifications because you're subscribed to this thread. - -:coffeescript - new Subscription("#{toggle_subscription_namespace_project_issue_path(@issue.project.namespace, @project, @issue)}") diff --git a/app/views/projects/issues/_issues.html.haml b/app/views/projects/issues/_issues.html.haml deleted file mode 100644 index 5d243adb5fe4742e97328a5e12f30733d4e511e4..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/_issues.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -.panel.panel-default - %ul.well-list.issues-list - = render @issues - - if @issues.blank? - %li - .nothing-here-block No issues to show - -- if @issues.present? - .pull-right - %span.issue_counter #{@issues.total_count} - issues for this filter - - = paginate @issues, theme: "gitlab" diff --git a/app/views/projects/issues/edit.html.haml b/app/views/projects/issues/edit.html.haml deleted file mode 100644 index b1bc3ba0eba684a146b503fa89225bda4614e840..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/edit.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "form" diff --git a/app/views/projects/issues/index.atom.builder b/app/views/projects/issues/index.atom.builder deleted file mode 100644 index 126f2c07faaa68192fc4b4a09dc8586eced6c497..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/index.atom.builder +++ /dev/null @@ -1,12 +0,0 @@ -xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do - xml.title "#{@project.name} issues" - xml.link :href => namespace_project_issues_url(@project.namespace, @project, :atom), :rel => "self", :type => "application/atom+xml" - xml.link :href => namespace_project_issues_url(@project.namespace, @project), :rel => "alternate", :type => "text/html" - xml.id namespace_project_issues_url(@project.namespace, @project) - xml.updated @issues.first.created_at.strftime("%Y-%m-%dT%H:%M:%SZ") if @issues.any? - - @issues.each do |issue| - issue_to_atom(xml, issue) - end -end diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml deleted file mode 100644 index d3c7ae24a752f4b3298e9951c94de9bf67511b9f..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/index.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -.append-bottom-10 - .pull-right - .pull-left - - if current_user - .hidden-xs.pull-left - = link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do - %i.fa.fa-rss - - = render 'shared/issuable_search_form', path: namespace_project_issues_path(@project.namespace, @project) - - - if can? current_user, :write_issue, @project - = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do - %i.fa.fa-plus - New Issue - - = render 'shared/issuable_filter' - -.issues-holder - = render "issues" diff --git a/app/views/projects/issues/new.html.haml b/app/views/projects/issues/new.html.haml deleted file mode 100644 index b1bc3ba0eba684a146b503fa89225bda4614e840..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/new.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "form" diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml deleted file mode 100644 index bd28d8a1db29a82f6f1cde6a54d7300a21606ebc..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/show.html.haml +++ /dev/null @@ -1,40 +0,0 @@ -.issue - .issue-details - %h4.page-title - .issue-box{ class: issue_box_class(@issue) } - - if @issue.closed? - Closed - - else - Open - Issue ##{@issue.iid} - %small.creator - · created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)} - - .pull-right - - if can?(current_user, :write_issue, @project) - = link_to new_namespace_project_issue_path(@project.namespace, @project), class: "btn btn-grouped new-issue-link", title: "New Issue", id: "new_issue_link" do - %i.fa.fa-plus - New Issue - - if can?(current_user, :modify_issue, @issue) - - if @issue.closed? - = link_to 'Reopen', issue_path(@issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen" - - else - = link_to 'Close', issue_path(@issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close", title: "Close Issue" - - = link_to edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: "btn btn-grouped issuable-edit" do - %i.fa.fa-pencil-square-o - Edit - - %hr - %h2.issue-title - = gfm escape_once(@issue.title) - %div - - if @issue.description.present? - .description - .wiki - = preserve do - = markdown(@issue.description, parse_tasks: true) - - %hr - .issue-discussion - = render "projects/issues/discussion" diff --git a/app/views/projects/issues/update.js.haml b/app/views/projects/issues/update.js.haml deleted file mode 100644 index 1d38662bff8f18237bdbab4f5d1d76e635849852..0000000000000000000000000000000000000000 --- a/app/views/projects/issues/update.js.haml +++ /dev/null @@ -1,17 +0,0 @@ -- if params[:status_only] - - if @issue.valid? - :plain - $("##{dom_id(@issue)}").fadeOut(); -- elsif params[:issue_context] - $('.context').html("#{escape_javascript(render partial: 'issue_context', locals: { issue: @issue })}"); - $('.context').effect('highlight'); - - if @issue.milestone - $('.milestone-nav-link').replaceWith("| Milestone #{escape_javascript(link_to @issue.milestone.title, namespace_project_milestone_path(@issue.project.namespace, @issue.project, @issue.milestone))}") - - else - $('.milestone-nav-link').html('') - - -$('select.select2').select2({width: 'resolve', dropdownAutoWidth: true}) -$('.edit-issue.inline-update input[type="submit"]').hide(); -new UsersSelect() -new Issue(); diff --git a/app/views/projects/labels/_label.html.haml b/app/views/projects/labels/_label.html.haml deleted file mode 100644 index 82829452862406d24f4592ac91c03b0b6bca5fe0..0000000000000000000000000000000000000000 --- a/app/views/projects/labels/_label.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%li{id: dom_id(label)} - = render_colored_label(label) - .pull-right - %strong.append-right-20 - = link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do - = pluralize label.open_issues_count, 'open issue' - - - if can? current_user, :admin_label, @project - = link_to 'Edit', edit_namespace_project_label_path(@project.namespace, @project, label), class: 'btn' - = link_to 'Remove', namespace_project_label_path(@project.namespace, @project, label), class: 'btn btn-remove remove-row', method: :delete, remote: true, data: {confirm: "Remove this label? Are you sure?"} diff --git a/app/views/projects/labels/destroy.js.haml b/app/views/projects/labels/destroy.js.haml deleted file mode 100644 index 1b4c83ab0979ff45905f9d5d17171015e80dc66d..0000000000000000000000000000000000000000 --- a/app/views/projects/labels/destroy.js.haml +++ /dev/null @@ -1,2 +0,0 @@ -- if @project.labels.size == 0 - $('.labels').load(document.URL + ' .light-well').hide().fadeIn(1000) diff --git a/app/views/projects/labels/edit.html.haml b/app/views/projects/labels/edit.html.haml deleted file mode 100644 index e003d1dfe7f586ffffed167502e51f428ddbb9be..0000000000000000000000000000000000000000 --- a/app/views/projects/labels/edit.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -%h3 - Edit label - %span.light #{@label.name} -.back-link - = link_to namespace_project_labels_path(@project.namespace, @project) do - ← To labels list -%hr -= render 'form' diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml deleted file mode 100644 index 0700e72d39c8e659a4195a009552d6e0383c28df..0000000000000000000000000000000000000000 --- a/app/views/projects/labels/index.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -- if can? current_user, :admin_label, @project - = link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do - New label -%h3.page-title - Labels -%hr - -.labels - - if @labels.present? - %ul.bordered-list.manage-labels-list - = render @labels - = paginate @labels, theme: 'gitlab' - - else - .light-well - .nothing-here-block Create first label or #{link_to 'generate', generate_namespace_project_labels_path(@project.namespace, @project), method: :post} default set of labels diff --git a/app/views/projects/labels/new.html.haml b/app/views/projects/labels/new.html.haml deleted file mode 100644 index 0683ed5d4fbcf6ae9f5b0cfb3e783cc7c6084654..0000000000000000000000000000000000000000 --- a/app/views/projects/labels/new.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%h3 New label -.back-link - = link_to namespace_project_labels_path(@project.namespace, @project) do - ← To labels list -%hr -= render 'form' diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml deleted file mode 100644 index eb72eaabd8b9482c5e90e423ffc1f595304ab35d..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/_discussion.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -- content_for :note_actions do - - if can?(current_user, :modify_merge_request, @merge_request) - - if @merge_request.open? - = link_to 'Close', merge_request_path(@merge_request, merge_request: {state_event: :close }), method: :put, class: "btn btn-grouped btn-close close-mr-link js-note-target-close", title: "Close merge request" - - if @merge_request.closed? - = link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request" - -.row - %section.col-md-9 - .votes-holder.pull-right - #votes= render 'votes/votes_block', votable: @merge_request - = render "projects/merge_requests/show/participants" - = render "projects/notes/notes_with_form" - %aside.col-md-3 - .issuable-affix - .clearfix - %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} - = cross_project_reference(@project, @merge_request) - %hr - .context - = render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request } - - - if @merge_request.labels.any? - .issuable-context-title - %label Labels - .merge-request-show-labels - - @merge_request.labels.each do |label| - = link_to namespace_project_merge_requests_path(@project.namespace, @project, label_name: label.name) do - = render_colored_label(label) - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml deleted file mode 100644 index 1c7160bce5fb495190ca0732f7991365ed18ba4e..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/_form.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form' } do |f| - .merge-request-form-info - = render 'projects/issuable_form', f: f, issuable: @merge_request - -:javascript - disableButtonIfEmptyField("#merge_request_title", ".btn-save"); - $('.assign-to-me-link').on('click', function(e){ - $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change"); - e.preventDefault(); - }); - - window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}"; diff --git a/app/views/projects/merge_requests/_head.html.haml b/app/views/projects/merge_requests/_head.html.haml deleted file mode 100644 index 19e4dab874bcd9e805232b5abf8bd6aa1c2f2ab7..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/_head.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -.top-tabs - = link_to namespace_project_merge_requests_path(@project.namespace, @project), class: "tab #{'active' if current_page?(namespace_project_merge_requests_path(@project.namespace, @project)) }" do - %span - Merge Requests - diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml deleted file mode 100644 index 4f30d1e69f79fd0525bfb4a290bffc15ad19f011..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ /dev/null @@ -1,48 +0,0 @@ -%li{ class: mr_css_classes(merge_request) } - .merge-request-title - %span.str-truncated - = link_to_gfm merge_request.title, merge_request_path(merge_request), class: "row_title" - .pull-right.light - - if merge_request.merged? - %span - %i.fa.fa-check - MERGED - - elsif merge_request.closed? - %span - %i.fa.fa-close - CLOSED - - else - %span.hidden-xs.hidden-sm - %span.label-branch< - %i.fa.fa-code-fork - %span= merge_request.target_branch - - note_count = merge_request.mr_and_commit_notes.user.count - - if note_count > 0 -   - %span - %i.fa.fa-comments - = note_count - .merge-request-info - = link_to "##{merge_request.iid}", merge_request_path(merge_request), class: "light" - - if merge_request.assignee - assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)} - - else - Unassigned - - if merge_request.votes_count > 0 - = render 'votes/votes_inline', votable: merge_request - - if merge_request.milestone_id? - %span - %i.fa.fa-clock-o - = merge_request.milestone.title - - if merge_request.tasks? - %span.task-status - = merge_request.task_status - - - .pull-right.hidden-xs - %small updated #{time_ago_with_tooltip(merge_request.updated_at, 'bottom', 'merge_request_updated_ago')} - - .merge-request-labels - - merge_request.labels.each do |label| - = link_to namespace_project_merge_requests_path(merge_request.project.namespace, merge_request.project, label_name: label.name) do - = render_colored_label(label) diff --git a/app/views/projects/merge_requests/_merge_requests.html.haml b/app/views/projects/merge_requests/_merge_requests.html.haml deleted file mode 100644 index b8a0ca9a42f31cf6aaa35adaa798e209fd2fdd34..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/_merge_requests.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -.panel.panel-default - %ul.well-list.mr-list - = render @merge_requests - - if @merge_requests.blank? - %li - .nothing-here-block No merge requests to show - -- if @merge_requests.present? - .pull-right - %span.cgray.pull-right #{@merge_requests.total_count} merge requests for this filter - - = paginate @merge_requests, theme: "gitlab" - diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml deleted file mode 100644 index 17e76059fdbc4664ff23f3df89bd947325074b54..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/_new_compare.html.haml +++ /dev/null @@ -1,89 +0,0 @@ -%h3.page-title Compare branches for new Merge Request -%hr - -= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: new_namespace_project_merge_request_path(@project.namespace, @project), method: :get, html: { class: "merge-request-form form-inline" } do |f| - .hide.alert.alert-danger.mr-compare-errors - .merge-request-branches.row - .col-md-6 - .panel.panel-default - .panel-heading - %strong Source branch - .panel-body - = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted? }) -   - = f.select(:source_branch, @merge_request.source_branches, { include_blank: "Select branch" }, {class: 'source_branch select2 span2'}) - .panel-footer - .mr_source_commit - - .col-md-6 - .panel.panel-default - .panel-heading - %strong Target branch - .panel-body - - projects = @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project] - = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace', f.object.target_project_id), {}, { class: 'target_project select2 span3', disabled: @merge_request.persisted? }) -   - = f.select(:target_branch, @merge_request.target_branches, { include_blank: "Select branch" }, {class: 'target_branch select2 span2'}) - .panel-footer - .mr_target_commit - - - if @merge_request.errors.any? - .alert.alert-danger - - @merge_request.errors.full_messages.each do |msg| - %div= msg - - - elsif @merge_request.source_branch.present? && @merge_request.target_branch.present? - - if @merge_request.compare_failed - .alert.alert-danger - %h4 Compare failed - %p We can't compare selected branches. It may be because of huge diff or satellite timeout. Please try again or select different branches. - - else - .light-well - .center - %h4 - There isn't anything to merge. - %p.slead - - if @merge_request.source_branch == @merge_request.target_branch - You'll need to use different branch names to get a valid comparison. - - else - %span.label-branch #{@merge_request.source_branch} - and - %span.label-branch #{@merge_request.target_branch} - are the same. - - - %hr - = f.submit 'Compare branches', class: "btn btn-primary mr-compare-btn" - -:javascript - var source_branch = $("#merge_request_source_branch") - , target_branch = $("#merge_request_target_branch") - , target_project = $("#merge_request_target_project_id"); - - $.get("#{branch_from_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {ref: source_branch.val() }); - $.get("#{branch_to_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {target_project_id: target_project.val(),ref: target_branch.val() }); - - target_project.on("change", function() { - $.get("#{update_branches_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {target_project_id: $(this).val() }); - }); - source_branch.on("change", function() { - $.get("#{branch_from_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {ref: $(this).val() }); - $(".mr-compare-errors").fadeOut(); - $(".mr-compare-btn").enable(); - }); - target_branch.on("change", function() { - $.get("#{branch_to_namespace_project_merge_requests_path(@source_project.namespace, @source_project)}", {target_project_id: target_project.val(),ref: $(this).val() }); - $(".mr-compare-errors").fadeOut(); - $(".mr-compare-btn").enable(); - }); - - -:coffeescript - - $(".merge-request-form").on 'submit', -> - if $("#merge_request_source_branch").val() is "" or $('#merge_request_target_branch').val() is "" - $(".mr-compare-errors").html("You must select source and target branch to proceed") - $(".mr-compare-errors").fadeIn() - event.preventDefault() - return - diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml deleted file mode 100644 index d986ce67c0c6b2588e92bebd783a360bc4772445..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ /dev/null @@ -1,123 +0,0 @@ -%h3.page-title - New merge request -%p.slead - From - %strong.label-branch #{@merge_request.source_project_namespace}:#{@merge_request.source_branch} - %span into - %strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch} - - %span.pull-right - = link_to 'Change branches', new_namespace_project_merge_request_path(@project.namespace, @project) - -= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: "merge-request-form form-horizontal gfm-form" } do |f| - .merge-request-form-info - .form-group - = f.label :title, class: 'control-label' do - %strong Title * - .col-sm-10 - = f.text_field :title, maxlength: 255, autofocus: true, class: 'form-control pad js-gfm-input', required: true - .form-group.issuable-description - = f.label :description, 'Description', class: 'control-label' - .col-sm-10 - = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do - = render 'projects/zen', f: f, attr: :description, classes: 'description form-control' - - .col-sm-12-hint - .pull-left - Parsed with - #{link_to 'Gitlab Flavored Markdown', help_page_path('markdown', 'markdown'), target: '_blank'}. - .pull-right - Attach files by dragging & dropping - or #{link_to 'selecting them', '#', class: 'markdown-selector'}. - - .clearfix - .error-alert - %hr - .form-group - .issue-assignee - = f.label :assignee_id, class: 'control-label' do - %i.fa.fa-user - Assign to - .col-sm-10 - = users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id, project_id: @merge_request.target_project_id) -   - = link_to 'Assign to me', '#', class: 'btn assign-to-me-link' - .form-group - .issue-milestone - = f.label :milestone_id, class: 'control-label' do - %i.fa.fa-clock-o - Milestone - .col-sm-10 - - if milestone_options(@merge_request).present? - = f.select(:milestone_id, milestone_options(@merge_request), {include_blank: 'Select milestone'}, {class: 'select2'}) - - else - %span.light No open milestones available. -   - - if can? current_user, :admin_milestone, @merge_request.target_project - = link_to 'Create new milestone', new_namespace_project_milestone_path(@merge_request.target_project.namespace, @merge_request.target_project), target: :blank - .form-group - = f.label :label_ids, class: 'control-label' do - %i.fa.fa-tag - Labels - .col-sm-10 - - if @merge_request.target_project.labels.any? - = f.collection_select :label_ids, @merge_request.target_project.labels.all, :id, :name, {selected: @merge_request.label_ids}, multiple: true, class: 'select2' - - else - %span.light No labels yet. -   - - if can? current_user, :admin_label, @merge_request.target_project - = link_to 'Create new label', new_namespace_project_label_path(@merge_request.target_project.namespace, @merge_request.target_project), target: :blank - - .form-actions - - if guide_url = contribution_guide_url(@target_project) - %p - Please review the - %strong #{link_to 'guidelines for contribution', guide_url} - to this repository. - = f.hidden_field :source_project_id - = f.hidden_field :source_branch - = f.hidden_field :target_project_id - = f.hidden_field :target_branch - = f.submit 'Submit merge request', class: 'btn btn-create' - -.mr-compare.merge-request - %ul.nav.nav-tabs.merge-request-tabs - %li.commits-tab{data: {action: 'commits'}} - = link_to url_for(params) do - %i.fa.fa-history - Commits - %span.badge= @commits.size - %li.diffs-tab{data: {action: 'diffs'}} - = link_to url_for(params) do - %i.fa.fa-list-alt - Changes - %span.badge= @diffs.size - - .commits.tab-content - = render "projects/commits/commits", project: @project - .diffs.tab-content - - if @diffs.present? - = render "projects/diffs/diffs", diffs: @diffs, project: @project - - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE - .alert.alert-danger - %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits. - %p To preserve performance the line changes are not shown. - - else - .alert.alert-danger - %h4 This comparison includes a huge diff. - %p To preserve performance the line changes are not shown. - -:javascript - $('.assign-to-me-link').on('click', function(e){ - $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change"); - e.preventDefault(); - }); - - window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}"; - -:javascript - var merge_request - merge_request = new MergeRequest({ - action: 'commits' - }); - diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml deleted file mode 100644 index a74aede4e6bacba98678caafce79a91a7ddf2009..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/_show.html.haml +++ /dev/null @@ -1,77 +0,0 @@ -.merge-request{'data-url' => merge_request_path(@merge_request)} - .merge-request-details - = render "projects/merge_requests/show/mr_title" - %hr - = render "projects/merge_requests/show/mr_box" - %hr - .append-bottom-20 - .slead - %span From - - if @merge_request.for_fork? - %strong.label-branch< - - if @merge_request.source_project - = link_to @merge_request.source_project_namespace, namespace_project_path(@merge_request.source_project.namespace, @merge_request.source_project) - - else - \ #{@merge_request.source_project_namespace} - \:#{@merge_request.source_branch} - %span into - %strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch} - - else - %strong.label-branch #{@merge_request.source_branch} - %span into - %strong.label-branch #{@merge_request.target_branch} - - if @merge_request.open? - %span.pull-right - .btn-group - %a.btn.dropdown-toggle{ data: {toggle: :dropdown} } - %i.fa.fa-download - Download as - %span.caret - %ul.dropdown-menu - %li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch) - %li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff) - - = render "projects/merge_requests/show/how_to_merge" - = render "projects/merge_requests/show/state_widget" - - - if @commits.present? - %ul.nav.nav-tabs.merge-request-tabs - %li.notes-tab{data: {action: 'notes'}} - = link_to merge_request_path(@merge_request) do - %i.fa.fa-comments - Discussion - %span.badge= @merge_request.mr_and_commit_notes.user.count - %li.commits-tab{data: {action: 'commits'}} - = link_to merge_request_path(@merge_request), title: 'Commits' do - %i.fa.fa-history - Commits - %span.badge= @commits.size - %li.diffs-tab{data: {action: 'diffs'}} - = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) do - %i.fa.fa-list-alt - Changes - %span.badge= @merge_request.diffs.size - - .notes.tab-content.voting_notes#notes{ class: (controller.action_name == 'show') ? "" : "hide" } - = render "projects/merge_requests/discussion" - .commits.tab-content - = render "projects/merge_requests/show/commits" - .diffs.tab-content - - if current_page?(action: 'diffs') - = render "projects/merge_requests/show/diffs" - - .mr-loading-status - = spinner - - -:javascript - var merge_request; - - merge_request = new MergeRequest({ - url_to_automerge_check: "#{automerge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", - check_enable: #{@merge_request.unchecked? ? "true" : "false"}, - url_to_ci_check: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}", - ci_enable: #{@project.ci_service ? "true" : "false"}, - current_status: "#{@merge_request.merge_status_name}", - action: "#{controller.action_name}" - }); diff --git a/app/views/projects/merge_requests/automerge.js.haml b/app/views/projects/merge_requests/automerge.js.haml deleted file mode 100644 index a53cbb150a41fc7f5e3a004c86496127789406da..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/automerge.js.haml +++ /dev/null @@ -1,6 +0,0 @@ --if @status - :plain - merge_request.mergeInProgress(); --else - :plain - merge_request.alreadyOrCannotBeMerged() diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml deleted file mode 100644 index 8372afa61b53b4cb5eb1de3615f725ec2b48cf93..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/branch_from.js.haml +++ /dev/null @@ -1,2 +0,0 @@ -:plain - $(".mr_source_commit").html("#{commit_to_html(@commit, @source_project, false)}"); diff --git a/app/views/projects/merge_requests/branch_to.js.haml b/app/views/projects/merge_requests/branch_to.js.haml deleted file mode 100644 index f7ede0ded53d42ce7b1a801ec182fd9e84f6c296..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/branch_to.js.haml +++ /dev/null @@ -1,2 +0,0 @@ -:plain - $(".mr_target_commit").html("#{commit_to_html(@commit, @target_project, false)}"); diff --git a/app/views/projects/merge_requests/diffs.html.haml b/app/views/projects/merge_requests/diffs.html.haml deleted file mode 100644 index 2a5b8b1441ef89345d4d5357b4f5b557d80fe7e7..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/diffs.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "show" diff --git a/app/views/projects/merge_requests/edit.html.haml b/app/views/projects/merge_requests/edit.html.haml deleted file mode 100644 index 839c63986ab36a155125e67a5739f0702dd8ef6e..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/edit.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h3.page-title - = "Edit merge request ##{@merge_request.iid}" -%hr -= render 'form' diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml deleted file mode 100644 index d7992bdd19ea8a0412d94cebcaa28598514c83ff..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/index.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -.append-bottom-10 - .pull-right - = render 'shared/issuable_search_form', path: namespace_project_merge_requests_path(@project.namespace, @project) - - - if can? current_user, :write_merge_request, @project - = link_to new_namespace_project_merge_request_path(@project.namespace, @project), class: "btn btn-new pull-left", title: "New Merge Request" do - %i.fa.fa-plus - New Merge Request - = render 'shared/issuable_filter' -.merge-requests-holder - = render 'merge_requests' diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml deleted file mode 100644 index b9c466657de4f01fe66edf0f9f530e8664dfc9db..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/invalid.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -.merge-request - = render "projects/merge_requests/show/mr_title" - = render "projects/merge_requests/show/mr_box" - - .alert.alert-danger - %p - We cannot render this merge request properly because - - if @merge_request.for_fork? && !@merge_request.source_project - fork project was removed - - elsif !@merge_request.source_branch_exists? - %span.label.label-inverse= @merge_request.source_branch - does not exist in - %span.label.label-info= @merge_request.source_project_path - - elsif !@merge_request.target_branch_exists? - %span.label.label-inverse= @merge_request.target_branch - does not exist in - %span.label.label-info= @merge_request.target_project_path - - else - of internal error - - %strong - Please close Merge Request or change branches with existing one - diff --git a/app/views/projects/merge_requests/new.html.haml b/app/views/projects/merge_requests/new.html.haml deleted file mode 100644 index 4756903d0e00465a47b0bcdd5cfa93cd0a4414c9..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/new.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -- if @merge_request.can_be_created - = render 'new_submit' -- else - = render 'new_compare' diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml deleted file mode 100644 index 2a5b8b1441ef89345d4d5357b4f5b557d80fe7e7..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "show" diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml deleted file mode 100644 index 3b7f283daf0468774e60114d0c3490d26c71cefc..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_commits.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "projects/commits/commits", project: @merge_request.source_project diff --git a/app/views/projects/merge_requests/show/_context.html.haml b/app/views/projects/merge_requests/show/_context.html.haml deleted file mode 100644 index 105562fb05e31bfa02caae672989f52a1533ac7b..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_context.html.haml +++ /dev/null @@ -1,48 +0,0 @@ -= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], remote: true, html: {class: 'edit-merge_request inline-update'} do |f| - %div.prepend-top-20 - .issuable-context-title - %label - Assignee: - - if @merge_request.assignee - %strong= link_to_member(@project, @merge_request.assignee, size: 24) - - else - none - .issuable-context-selectbox - - if can?(current_user, :modify_merge_request, @merge_request) - = users_select_tag('merge_request[assignee_id]', placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: @merge_request.assignee_id, null_user: true) - - %div.prepend-top-20.clearfix - .issuable-context-title - %label - Milestone: - - if @merge_request.milestone - %span.back-to-milestone - = link_to namespace_project_milestone_path(@project.namespace, @project, @merge_request.milestone) do - %strong - %i.fa.fa-clock-o - = @merge_request.milestone.title - - else - none - .issuable-context-selectbox - - if can?(current_user, :modify_merge_request, @merge_request) - = f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2 select2-compact js-select2 js-milestone'}) - = hidden_field_tag :merge_request_context - = f.submit class: 'btn' - - - if current_user - %div.prepend-top-20.clearfix - .issuable-context-title - %label - Subscription: - %button.btn.btn-block.subscribe-button - %i.fa.fa-eye - %span= @merge_request.subscribed?(current_user) ? "Unsubscribe" : "Subscribe" - - subscribtion_status = @merge_request.subscribed?(current_user) ? "subscribed" : "unsubscribed" - .subscription-status{"data-status" => subscribtion_status} - .description-block.unsubscribed{class: ( "hidden" if @merge_request.subscribed?(current_user) )} - You're not receiving notifications from this thread. - .description-block.subscribed{class: ( "hidden" unless @merge_request.subscribed?(current_user) )} - You're receiving notifications because you're subscribed to this thread. - -:coffeescript - new Subscription("#{toggle_subscription_namespace_project_merge_request_path(@merge_request.project.namespace, @project, @merge_request)}") diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml deleted file mode 100644 index 786b5f39063327cf28f8dca26d3f89965b46f7cd..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_diffs.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -- if @merge_request_diff.collected? - = render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project -- elsif @merge_request_diff.empty? - .nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch} -- else - .alert.alert-warning - %h4 - Changes view for this comparison is extremely large. - %p - You can - = link_to "download it", merge_request_path(@merge_request, format: :diff), class: "vlink" - instead. diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/show/_how_to_merge.html.haml deleted file mode 100644 index 63db4b30968c1fd23f8ad7e110df5ca79e6e9fdd..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_how_to_merge.html.haml +++ /dev/null @@ -1,53 +0,0 @@ -%div#modal_merge_info.modal.hide - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3 How to merge - .modal-body - - if @merge_request.for_fork? - - source_remote = @merge_request.source_project.namespace.nil? ? "source" :@merge_request.source_project.namespace.path - - target_remote = @merge_request.target_project.namespace.nil? ? "target" :@merge_request.target_project.namespace.path - %p - %strong Step 1. - Fetch the code and create a new branch pointing to it - %pre.dark - :preserve - git fetch #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch} - git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} FETCH_HEAD - %p - %strong Step 2. - Merge the branch and push the changes to GitLab - %pre.dark - :preserve - git checkout #{@merge_request.target_branch} - git merge --no-ff #{@merge_request.source_project_path}-#{@merge_request.source_branch} - git push origin #{@merge_request.target_branch} - - else - %p - %strong Step 1. - Update the repo and checkout the branch we are going to merge - %pre.dark - :preserve - git fetch origin - git checkout -b #{@merge_request.source_branch} origin/#{@merge_request.source_branch} - %p - %strong Step 2. - Merge the branch and push the changes to GitLab - %pre.dark - :preserve - git checkout #{@merge_request.target_branch} - git merge --no-ff #{@merge_request.source_branch} - git push origin #{@merge_request.target_branch} - - -:javascript - $(function(){ - var modal = $('#modal_merge_info').modal({modal: true, show:false}); - $('.how_to_merge_link').bind("click", function(){ - modal.show(); - }); - $('.modal-header .close').bind("click", function(){ - modal.hide(); - }) - }) diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml deleted file mode 100644 index 9f51f84d40024e3f19be9df20b618119fe9bbfda..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_mr_accept.html.haml +++ /dev/null @@ -1,74 +0,0 @@ -- unless @allowed_to_merge - - if @project.archived? - %p - %strong Archived projects cannot be committed to! - - else - .automerge_widget.cannot_be_merged.hide - %strong This can't be merged automatically, even if it could be merged you don't have the permission to do so. - .automerge_widget.can_be_merged.hide - %strong This can be merged automatically but you don't have the permission to do so. - - -- if @show_merge_controls - .automerge_widget.can_be_merged.hide - .clearfix - = form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post do |f| - .accept-merge-holder.clearfix.js-toggle-container - .accept-action - = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" - - if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork? - .accept-control.checkbox - = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do - = check_box_tag :should_remove_source_branch - Remove source-branch - .accept-control - = link_to "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" do - %i.fa.fa-edit - Modify commit message - .js-toggle-content.hide.prepend-top-20 - = render 'shared/commit_message_container', params: params, - text: @merge_request.merge_commit_message, - rows: 14, hint: true - - %br - .light - If you still want to merge this request manually - use - %strong - = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal" - - - .automerge_widget.no_satellite.hide - %p - %span - %strong This repository does not have satellite. Ask an administrator to fix this issue - - .automerge_widget.cannot_be_merged.hide - %h4 - This request can't be merged with GitLab. - You should do it manually with - %strong - = link_to "#modal_merge_info", class: "underlined-link how_to_merge_link", title: "How To Merge", "data-toggle" => "modal" do - command line - - %p - %button.btn.disabled - %i.fa.fa-warning - Accept Merge Request -   - This usually happens when git can not resolve conflicts between branches automatically. - - .automerge_widget.unchecked - %p - %strong - %i.fa.fa-spinner.fa-spin - Checking for ability to automatically merge… - - .automerge_widget.already_cannot_be_merged.hide - %p - %strong This merge request can not be merged. Try to reload the page. - - .merge-in-progress.hide - %p - %i.fa.fa-spinner.fa-spin -   - Merge is in progress. Please wait. Page will be automatically reloaded.   diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml deleted file mode 100644 index ada9ae58b8f7d34905393b8a3f4d0d74be8ba5f8..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -%h2.issue-title - = gfm escape_once(@merge_request.title) - -%div - - if @merge_request.description.present? - .description - .wiki - = preserve do - = markdown(@merge_request.description, parse_tasks: true) diff --git a/app/views/projects/merge_requests/show/_mr_ci.html.haml b/app/views/projects/merge_requests/show/_mr_ci.html.haml deleted file mode 100644 index ffa3f7b0e36a120122527933f918f727056b69a7..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_mr_ci.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -- if @commits.any? - .ci_widget.ci-success{style: "display:none"} - %i.fa.fa-check - %span CI build passed - for #{@merge_request.last_commit_short_sha}. - = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - - .ci_widget.ci-failed{style: "display:none"} - %i.fa.fa-times - %span CI build failed - for #{@merge_request.last_commit_short_sha}. - = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - - [:running, :pending].each do |status| - .ci_widget{class: "ci-#{status}", style: "display:none"} - %i.fa.fa-clock-o - %span CI build #{status} - for #{@merge_request.last_commit_short_sha}. - = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - .ci_widget - %i.fa.fa-spinner - Checking for CI status for #{@merge_request.last_commit_short_sha} - - .ci_widget.ci-canceled{style: "display:none"} - %i.fa.fa-times - %span CI build canceled - for #{@merge_request.last_commit_short_sha}. - = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink" - - .ci_widget.ci-error{style: "display:none"} - %i.fa.fa-times - %span Cannot connect to the CI server. Please check your settings and try again. diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml deleted file mode 100644 index 46e92a9c55845956ab4172ba1df1f0055b037317..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -%h4.page-title - .issue-box{ class: issue_box_class(@merge_request) } - - if @merge_request.merged? - Merged - - elsif @merge_request.closed? - Closed - - else - Open - = "Merge Request ##{@merge_request.iid}" - %small.creator - · - created by #{link_to_member(@project, @merge_request.author)} #{time_ago_with_tooltip(@merge_request.created_at)} - - .issue-btn-group.pull-right - - if can?(current_user, :modify_merge_request, @merge_request) - - if @merge_request.open? - = link_to 'Close', merge_request_path(@merge_request, merge_request: { state_event: :close }), method: :put, class: "btn btn-grouped btn-close", title: "Close merge request" - = link_to edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "btn btn-grouped issuable-edit", id: "edit_merge_request" do - %i.fa.fa-pencil-square-o - Edit - - if @merge_request.closed? - = link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-grouped btn-reopen reopen-mr-link", title: "Close merge request" diff --git a/app/views/projects/merge_requests/show/_no_accept.html.haml b/app/views/projects/merge_requests/show/_no_accept.html.haml deleted file mode 100644 index 423fcd48e253c5064f9862c91fb653bdddf281b1..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_no_accept.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -%h4 - Can't be merged -%p - This merge request can not be accepted because branch - - unless @merge_request.source_branch_exists? - %span.label.label-inverse= @merge_request.source_branch - does not exist in - %span.label.label-info= @merge_request.source_project_path - - else - %span.label.label-inverse= @merge_request.target_branch - does not exist in - %span.label.label-info= @merge_request.target_project_path - %br - %strong Please close this merge request or change branches with existing one diff --git a/app/views/projects/merge_requests/show/_participants.html.haml b/app/views/projects/merge_requests/show/_participants.html.haml deleted file mode 100644 index 9c93fa55fe60ddea43dd2512d18139e6ea00a97a..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_participants.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -.participants - %span #{@merge_request.participants(current_user).count} participants - - @merge_request.participants(current_user).each do |participant| - = link_to_member(@project, participant, name: false, size: 24) diff --git a/app/views/projects/merge_requests/show/_remove_source_branch.html.haml b/app/views/projects/merge_requests/show/_remove_source_branch.html.haml deleted file mode 100644 index 59cb85edfce11b934d39718c9500c9aea963c101..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_remove_source_branch.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -- if @source_branch.blank? - Source branch has been removed - -- elsif can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && @merge_request.merged? - .remove_source_branch_widget - %p Changes merged into #{@merge_request.target_branch}. You can remove source branch now - = link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-sm remove_source_branch" do - %i.fa.fa-times - Remove Source Branch - - .remove_source_branch_widget.failed.hide - Failed to remove source branch '#{@merge_request.source_branch}' - - .remove_source_branch_in_progress.hide - %i.fa.fa-spinner.fa-spin -   - Removing source branch '#{@merge_request.source_branch}'. Please wait. Page will be automatically reloaded.   diff --git a/app/views/projects/merge_requests/show/_state_widget.html.haml b/app/views/projects/merge_requests/show/_state_widget.html.haml deleted file mode 100644 index 44bd9347f514568c34b31d9c8c6f7b85e0abd8d6..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/show/_state_widget.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -.mr-state-widget - - if @merge_request.source_project.ci_service && @commits.any? - .mr-widget-heading - = render "projects/merge_requests/show/mr_ci" - .mr-widget-body - - if @merge_request.open? - - if @merge_request.source_branch_exists? && @merge_request.target_branch_exists? - = render "projects/merge_requests/show/mr_accept" - - else - = render "projects/merge_requests/show/no_accept" - - - if @merge_request.closed? - %h4 - Closed - - if @merge_request.closed_event - by #{link_to_member(@project, @merge_request.closed_event.author, avatar: false)} - #{time_ago_with_tooltip(@merge_request.closed_event.created_at)} - %p Changes were not merged into target branch - - - if @merge_request.merged? - %h4 - Merged - - if @merge_request.merge_event - by #{link_to_member(@project, @merge_request.merge_event.author, avatar: false)} - #{time_ago_with_tooltip(@merge_request.merge_event.created_at)} - = render "projects/merge_requests/show/remove_source_branch" - - - if @merge_request.locked? - %h4 - Merge in progress... - %p - Merging is in progress. While merging this request is locked and cannot be closed. - - - unless @commits.any? - %h4 Nothing to merge - %p - Nothing to merge from - %span.label-branch #{@merge_request.source_branch} - to - %span.label-branch #{@merge_request.target_branch} - %br - Try to use different branches or push new code. - - - if @closes_issues.present? && @merge_request.open? - .mr-widget-footer - %span - %i.fa.fa-check - Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'} - = succeed '.' do - != gfm(issues_sentence(@closes_issues)) diff --git a/app/views/projects/merge_requests/update.js.haml b/app/views/projects/merge_requests/update.js.haml deleted file mode 100644 index b4df1d20737468718827d968170df1696c4bb043..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/update.js.haml +++ /dev/null @@ -1,8 +0,0 @@ -- if params[:merge_request_context] - $('.context').html("#{escape_javascript(render partial: 'projects/merge_requests/show/context', locals: { issue: @issue })}"); - $('.context').effect('highlight'); - - new UsersSelect() - - $('select.select2').select2({width: 'resolve', dropdownAutoWidth: true}); - merge_request = new MergeRequest(); diff --git a/app/views/projects/merge_requests/update_branches.js.haml b/app/views/projects/merge_requests/update_branches.js.haml deleted file mode 100644 index ca21b3bc0deb365c4db2f3ecc72576c80cd5e4e4..0000000000000000000000000000000000000000 --- a/app/views/projects/merge_requests/update_branches.js.haml +++ /dev/null @@ -1,9 +0,0 @@ -:plain - $(".target_branch").html("#{escape_javascript(options_for_select(@target_branches))}"); - - $('select.target_branch').select2({ - width: 'resolve', - dropdownAutoWidth: true - }); - - $(".mr_target_commit").html(""); diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml deleted file mode 100644 index 95b7070ce5c55396029bba3488f64917e8741f6d..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/_form.html.haml +++ /dev/null @@ -1,54 +0,0 @@ -%h3.page-title= @milestone.new_record? ? "New Milestone" : "Edit Milestone ##{@milestone.iid}" -.back-link - = link_to namespace_project_milestones_path(@project.namespace, @project) do - ← To milestones - -%hr - -= form_for [@project.namespace.becomes(Namespace), @project, @milestone], html: {class: 'form-horizontal milestone-form gfm-form'} do |f| - -if @milestone.errors.any? - .alert.alert-danger - %ul - - @milestone.errors.full_messages.each do |msg| - %li= msg - .row - .col-md-6 - .form-group - = f.label :title, "Title", class: "control-label" - .col-sm-10 - = f.text_field :title, maxlength: 255, class: "form-control" - %p.hint Required - .form-group.milestone-description - = f.label :description, "Description", class: "control-label" - .col-sm-10 - = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do - = render 'projects/zen', f: f, attr: :description, classes: 'description form-control' - .hint - .pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}. - .pull-left Attach files by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. - .clearfix - .error-alert - .col-md-6 - .form-group - = f.label :due_date, "Due Date", class: "control-label" - .col-sm-10= f.hidden_field :due_date - .col-sm-10 - .datepicker - - .form-actions - - if @milestone.new_record? - = f.submit 'Create milestone', class: "btn-create btn" - = link_to "Cancel", namespace_project_milestones_path(@project.namespace, @project), class: "btn btn-cancel" - -else - = f.submit 'Save changes', class: "btn-save btn" - = link_to "Cancel", namespace_project_milestone_path(@project.namespace, @project, @milestone), class: "btn btn-cancel" - - -:javascript - disableButtonIfEmptyField("#milestone_title", ".btn-save"); - $( ".datepicker" ).datepicker({ - dateFormat: "yy-mm-dd", - onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) } - }).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#milestone_due_date').val())); - - window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}"; diff --git a/app/views/projects/milestones/_issue.html.haml b/app/views/projects/milestones/_issue.html.haml deleted file mode 100644 index 88fccfe4981c4e665c299729080f7b37fa2a85ab..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/_issue.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -%li{ id: dom_id(issue, 'sortable'), class: 'issue-row', 'data-iid' => issue.iid, 'data-url' => issue_path(issue) } - .pull-right.assignee-icon - - if issue.assignee - = image_tag avatar_icon(issue.assignee.email, 16), class: "avatar s16", alt: '' - %span - = link_to [@project.namespace.becomes(Namespace), @project, issue] do - %span.cgray ##{issue.iid} - = link_to_gfm issue.title, [@project.namespace.becomes(Namespace), @project, issue], title: issue.title - diff --git a/app/views/projects/milestones/_issues.html.haml b/app/views/projects/milestones/_issues.html.haml deleted file mode 100644 index 6e4df75a3dfaf3534a601c3566265074d799bed4..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/_issues.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list issues-sortable-list", id: "issues-list-#{id}", "data-state" => id } - - issues.sort_by(&:position).each do |issue| - = render 'issue', issue: issue - %li.light.ui-sort-disabled Drag and drop available diff --git a/app/views/projects/milestones/_merge_request.html.haml b/app/views/projects/milestones/_merge_request.html.haml deleted file mode 100644 index 0d7a118569a8943037af86bbadf8dd745cb799e8..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/_merge_request.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -%li{ id: dom_id(merge_request, 'sortable'), class: 'mr-row', 'data-iid' => merge_request.iid, 'data-url' => merge_request_path(merge_request) } - %span.str-truncated - = link_to [@project.namespace.becomes(Namespace), @project, merge_request] do - %span.cgray ##{merge_request.iid} - = link_to_gfm merge_request.title, [@project.namespace.becomes(Namespace), @project, merge_request], title: merge_request.title - .pull-right.assignee-icon - - if merge_request.assignee - = image_tag avatar_icon(merge_request.assignee.email, 16), class: "avatar s16", alt: '' diff --git a/app/views/projects/milestones/_merge_requests.html.haml b/app/views/projects/milestones/_merge_requests.html.haml deleted file mode 100644 index 00889a5eb248e90cd25a933b380bf278e8dca804..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/_merge_requests.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.panel.panel-default - .panel-heading= title - %ul{ class: "well-list merge_requests-sortable-list", id: "merge_requests-list-#{id}", "data-state" => id } - - merge_requests.sort_by(&:position).each do |merge_request| - = render 'merge_request', merge_request: merge_request - %li.light.ui-sort-disabled Drag and drop available diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml deleted file mode 100644 index 62360158ff94330e00fdd38394cb300bd7c16f76..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/_milestone.html.haml +++ /dev/null @@ -1,24 +0,0 @@ -%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone) } - .pull-right - - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? - = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-sm edit-milestone-link btn-grouped" do - %i.fa.fa-pencil-square-o - Edit - = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-sm btn-close" - %h4 - = link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) - - if milestone.expired? and not milestone.closed? - %span.cred (Expired) - %small - = milestone.expires_at - .row - .col-sm-6 - = link_to namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_id: milestone.id) do - = pluralize milestone.issues.count, 'Issue' -   - = link_to namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_id: milestone.id) do - = pluralize milestone.merge_requests.count, 'Merge Request' -   - %span.light #{milestone.percent_complete}% complete - .col-sm-6 - = milestone_progress_bar(milestone) diff --git a/app/views/projects/milestones/edit.html.haml b/app/views/projects/milestones/edit.html.haml deleted file mode 100644 index b1bc3ba0eba684a146b503fa89225bda4614e840..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/edit.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "form" diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml deleted file mode 100644 index d3eab8d6d7509d19cb1bba0bda2959999fc5974c..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/index.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -.pull-right - - if can? current_user, :admin_milestone, @project - = link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "pull-right btn btn-new", title: "New Milestone" do - %i.fa.fa-plus - New Milestone -= render 'shared/milestones_filter' - -.milestones - .panel.panel-default - %ul.well-list - = render @milestones - - - if @milestones.blank? - %li - .nothing-here-block No milestones to show - - = paginate @milestones, theme: "gitlab" diff --git a/app/views/projects/milestones/new.html.haml b/app/views/projects/milestones/new.html.haml deleted file mode 100644 index b1bc3ba0eba684a146b503fa89225bda4614e840..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/new.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render "form" diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml deleted file mode 100644 index 25cc00309658282dd2b31ce9c5942676f76fdd60..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/show.html.haml +++ /dev/null @@ -1,103 +0,0 @@ -%h4.page-title - .issue-box{ class: issue_box_class(@milestone) } - - if @milestone.closed? - Closed - - elsif @milestone.expired? - Expired - - else - Open - Milestone ##{@milestone.iid} - %small.creator - = @milestone.expires_at - .pull-right - - if can?(current_user, :admin_milestone, @project) - = link_to edit_namespace_project_milestone_path(@project.namespace, @project, @milestone), class: "btn btn-grouped" do - %i.fa.fa-pencil-square-o - Edit - - if @milestone.active? - = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-grouped" - - else - = link_to 'Reopen Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-grouped" - -%hr -- if @milestone.issues.any? && @milestone.can_be_closed? - .alert.alert-success - %span All issues for this milestone are closed. You may close milestone now. - -%h3.issue-title - = gfm escape_once(@milestone.title) -%div - - if @milestone.description.present? - .description - .wiki - = preserve do - = markdown @milestone.description - -%hr -.context - %p.lead - Progress: - #{@milestone.closed_items_count} closed - – - #{@milestone.open_items_count} open -   - %span.light #{@milestone.percent_complete}% complete - %span.pull-right= @milestone.expires_at - = milestone_progress_bar(@milestone) - - -%ul.nav.nav-tabs - %li.active - = link_to '#tab-issues', 'data-toggle' => 'tab' do - Issues - %span.badge= @issues.count - %li - = link_to '#tab-merge-requests', 'data-toggle' => 'tab' do - Merge Requests - %span.badge= @merge_requests.count - %li - = link_to '#tab-participants', 'data-toggle' => 'tab' do - Participants - %span.badge= @users.count - - - if @project.issues_enabled - .pull-right - = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { milestone_id: @milestone.id }), class: "btn btn-grouped", title: "New Issue" do - %i.fa.fa-plus - New Issue - = link_to 'Browse Issues', namespace_project_issues_path(@milestone.project.namespace, @milestone.project, milestone_id: @milestone.id), class: "btn edit-milestone-link btn-grouped" - -.tab-content - .tab-pane.active#tab-issues - .row - .col-md-4 - = render('issues', title: 'Unstarted Issues (open and unassigned)', issues: @issues.opened.unassigned, id: 'unassigned') - .col-md-4 - = render('issues', title: 'Ongoing Issues (open and assigned)', issues: @issues.opened.assigned, id: 'ongoing') - .col-md-4 - = render('issues', title: 'Completed Issues (closed)', issues: @issues.closed, id: 'closed') - - .tab-pane#tab-merge-requests - .row - .col-md-3 - = render('merge_requests', title: 'Work in progress (open and unassigned)', merge_requests: @merge_requests.opened.unassigned, id: 'unassigned') - .col-md-3 - = render('merge_requests', title: 'Waiting for merge (open and assigned)', merge_requests: @merge_requests.opened.assigned, id: 'ongoing') - .col-md-3 - = render('merge_requests', title: 'Declined (closed)', merge_requests: @merge_requests.declined, id: 'closed') - .col-md-3 - .panel.panel-primary - .panel-heading Merged - %ul.well-list - - @merge_requests.merged.each do |merge_request| - = render 'merge_request', merge_request: merge_request - - .tab-pane#tab-participants - %ul.bordered-list - - @users.each do |user| - %li - = link_to user, title: user.name, class: "darken" do - = image_tag avatar_icon(user.email, 32), class: "avatar s32" - %strong= truncate(user.name, lenght: 40) - %br - %small.cgray= user.username diff --git a/app/views/projects/milestones/update.js.haml b/app/views/projects/milestones/update.js.haml deleted file mode 100644 index 3ff84915e97f052a7e833a6812ae0d17b621d8df..0000000000000000000000000000000000000000 --- a/app/views/projects/milestones/update.js.haml +++ /dev/null @@ -1,2 +0,0 @@ -:plain - $('##{dom_id(@milestone)}').fadeOut(); diff --git a/app/views/projects/network/_head.html.haml b/app/views/projects/network/_head.html.haml deleted file mode 100644 index 415c98ec6a6aed0561730427d782f8db9e48a344..0000000000000000000000000000000000000000 --- a/app/views/projects/network/_head.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -.append-bottom-20 - = render partial: 'shared/ref_switcher', locals: {destination: 'graph'} - .pull-right.visible-lg.light You can move around the graph by using the arrow keys. diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml deleted file mode 100644 index c36bad1e94b6096af8c2e0b0b056aec3e330a6d2..0000000000000000000000000000000000000000 --- a/app/views/projects/network/show.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -= render "head" -.project-network - .controls - = form_tag namespace_project_network_path(@project.namespace, @project, @id), method: :get, class: 'form-inline network-form' do |f| - = text_field_tag :extended_sha1, @options[:extended_sha1], placeholder: "Input an extended SHA1 syntax", class: 'search-input form-control input-mx-250 search-sha' - = button_tag class: 'btn btn-success btn-search-sha' do - %i.fa.fa-search - .inline.prepend-left-20 - .checkbox.light - = label_tag :filter_ref do - = check_box_tag :filter_ref, 1, @options[:filter_ref] - %span Begin with the selected commit - - .network-graph - = spinner nil, true - -:javascript - disableButtonIfEmptyField('#extended_sha1', '.btn-search-sha') - - network_graph = new Network({ - url: '#{namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json))}', - commit_url: '#{namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s")}', - ref: '#{@ref}', - commit_id: '#{@commit.id}' - }) - new ShortcutsNetwork(network_graph.branch_graph) diff --git a/app/views/projects/network/show.json.erb b/app/views/projects/network/show.json.erb deleted file mode 100644 index dc82adcb2c640fd6c9da4208cfead0926eb9b302..0000000000000000000000000000000000000000 --- a/app/views/projects/network/show.json.erb +++ /dev/null @@ -1,23 +0,0 @@ -<% self.formats = ["html"] %> - -<%= raw( - { - days: @graph.days.compact.map { |d| [d.day, d.strftime("%b")] }, - commits: @graph.commits.map do |c| - { - parents: parents_zip_spaces(c.parents(@graph.map), c.parent_spaces), - author: { - name: c.author_name, - email: c.author_email, - icon: avatar_icon(c.author_email, 20) - }, - time: c.time, - space: c.spaces.first, - refs: get_refs(@graph.repo, c), - id: c.sha, - date: c.date, - message: c.message, - } - end - }.to_json -) %> diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml deleted file mode 100644 index a06c85b4251261b4934628cd4bac968224c9d966..0000000000000000000000000000000000000000 --- a/app/views/projects/new.html.haml +++ /dev/null @@ -1,120 +0,0 @@ -.project-edit-container - .project-edit-errors - = render 'projects/errors' - .project-edit-content - - = form_for @project, html: { class: 'new_project form-horizontal' } do |f| - .form-group.project-name-holder - = f.label :path, class: 'control-label' do - %strong Project path - .col-sm-10 - .input-group - = f.text_field :path, placeholder: "my-awesome-project", class: "form-control", tabindex: 1, autofocus: true - .input-group-addon - \.git - - - if current_user.can_select_namespace? - .form-group - = f.label :namespace_id, class: 'control-label' do - %span Namespace - .col-sm-10 - = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2} - - %hr - - .project-import.js-toggle-container - .form-group - %label.control-label Import project from - .col-sm-10 - - if github_import_enabled? - = link_to status_import_github_path, class: 'btn' do - %i.fa.fa-github - GitHub - - else - = link_to '#', class: 'how_to_import_link light btn' do - %i.fa.fa-github - GitHub - = render 'github_import_modal' - - - - if bitbucket_import_enabled? - = link_to status_import_bitbucket_path, class: 'btn' do - %i.fa.fa-bitbucket - Bitbucket - - else - = link_to '#', class: 'how_to_import_link light btn' do - %i.fa.fa-bitbucket - Bitbucket - = render 'bitbucket_import_modal' - - - unless request.host == 'gitlab.com' - - if gitlab_import_enabled? - = link_to status_import_gitlab_path, class: 'btn' do - %i.fa.fa-heart - GitLab.com - - else - = link_to '#', class: 'how_to_import_link light btn' do - %i.fa.fa-heart - GitLab.com - = render 'gitlab_import_modal' - - = link_to new_import_gitorious_path, class: 'btn' do - %i.icon-gitorious.icon-gitorious-small - Gitorious.org - - = link_to new_import_google_code_path, class: 'btn' do - %i.fa.fa-google - Google Code - - = link_to "#", class: 'btn js-toggle-button' do - %i.fa.fa-git - %span Any repo by URL - - .js-toggle-content.hide - .form-group.import-url-data - = f.label :import_url, class: 'control-label' do - %span Git repository URL - .col-sm-10 - = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git' - .well.prepend-top-20 - %ul - %li - The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL: https://username:password@gitlab.company.com/group/project.git. - %li - The import will time out after 4 minutes. For big repositories, use a clone/push combination. - %li - To migrate an SVN repository, check out #{link_to "this document", "http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"}. - - %hr.prepend-botton-10 - - .form-group - = f.label :description, class: 'control-label' do - Description - %span.light (optional) - .col-sm-10 - = f.text_area :description, placeholder: "Awesome project", class: "form-control", rows: 3, maxlength: 250, tabindex: 3 - = render "visibility_level", f: f, visibility_level: gitlab_config.default_projects_features.visibility_level, can_change_visibility_level: true - - .form-actions - = f.submit 'Create project', class: "btn btn-create project-submit", tabindex: 4 - - - if current_user.can_create_group? - .pull-right - .light - Need a group for several dependent projects? - = link_to new_group_path, class: "btn btn-xs" do - Create a group - -.save-project-loader.hide - .center - %h2 - %i.fa.fa-spinner.fa-spin - Creating project & repository. - %p Please wait a moment, this page will automatically refresh when ready. - -:coffeescript - $('.how_to_import_link').bind 'click', (e) -> - e.preventDefault() - import_modal = $(this).next(".modal").show() - $('.modal-header .close').bind 'click', -> - $(".modal").hide() diff --git a/app/views/projects/no_repo.html.haml b/app/views/projects/no_repo.html.haml deleted file mode 100644 index 720957e8336a1cc4ec51c05fdc0dce7ef7e1eeda..0000000000000000000000000000000000000000 --- a/app/views/projects/no_repo.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -%h2 - %i.fa.fa-warning - No repository - -%p.slead - The repository for this project does not exist. - %br - This means you can not push code until you create an empty repository or import existing one. -%hr - -.no-repo-actions - = link_to namespace_project_repository_path(@project.namespace, @project), method: :post, class: 'btn btn-primary' do - Create empty bare repository - - %strong.prepend-left-10.append-right-10 or - - = link_to new_namespace_project_import_path(@project.namespace, @project), class: 'btn' do - Import repository - -- if can? current_user, :remove_project, @project - .prepend-top-20 - = link_to 'Remove project', project_path(@project), data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-remove pull-right" diff --git a/app/views/projects/notes/_commit_discussion.html.haml b/app/views/projects/notes/_commit_discussion.html.haml deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/app/views/projects/notes/_diff_notes_with_reply.html.haml b/app/views/projects/notes/_diff_notes_with_reply.html.haml deleted file mode 100644 index c731baf0a651e225be51be50b74787999a2eb3f1..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_diff_notes_with_reply.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -- note = notes.first # example note --# Check if line want not changed since comment was left -- if !defined?(line) || line == note.diff_line - %tr.notes_holder - %td.notes_line{ colspan: 2 } - %span.discussion-notes-count - %i.fa.fa-comment - = notes.count - %td.notes_content - %ul.notes{ rel: note.discussion_id } - = render notes - .discussion-reply-holder - = link_to_reply_diff(note) diff --git a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml deleted file mode 100644 index 789f3e19fd2ec6378a110c64eea201aeb9e0385e..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -- note1 = notes1.present? ? notes1.first : nil -- note2 = notes2.present? ? notes2.first : nil - -%tr.notes_holder - - if note1 - %td.notes_line - %span.btn.disabled - %i.fa.fa-comment - = notes1.count - %td.notes_content.parallel - %ul.notes{ rel: note1.discussion_id } - = render notes1 - - .discussion-reply-holder - = link_to_reply_diff(note1) - - else - %td= "" - %td= "" - - - if note2 - %td.notes_line - %span.btn.disabled - %i.fa.fa-comment - = notes2.count - %td.notes_content.parallel - %ul.notes{ rel: note2.discussion_id } - = render notes2 - - .discussion-reply-holder - = link_to_reply_diff(note2) - - else - %td= "" - %td= "" - diff --git a/app/views/projects/notes/_discussion.html.haml b/app/views/projects/notes/_discussion.html.haml deleted file mode 100644 index b8068835b3ace9eb47c059def33c55d7b4fd9414..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_discussion.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -- note = discussion_notes.first -.timeline-entry - .timeline-entry-inner - .timeline-icon - = link_to user_path(note.author) do - = image_tag avatar_icon(note.author_email), class: "avatar s40" - .timeline-content - - if note.for_merge_request? - - (active_notes, outdated_notes) = discussion_notes.partition(&:active?) - = render "projects/notes/discussions/active", discussion_notes: active_notes if active_notes.length > 0 - = render "projects/notes/discussions/outdated", discussion_notes: outdated_notes if outdated_notes.length > 0 - - else - = render "projects/notes/discussions/commit", discussion_notes: discussion_notes diff --git a/app/views/projects/notes/_edit_form.html.haml b/app/views/projects/notes/_edit_form.html.haml deleted file mode 100644 index acb3991d2946a523d3d8e8b88ce48e4f6cbef87a..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_edit_form.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -.note-edit-form - = form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true do |f| - = note_target_fields(note) - = render layout: 'projects/md_preview', locals: { preview_class: "note-text" } do - = render 'projects/zen', f: f, attr: :note, - classes: 'note_text js-note-text' - - .comment-hints.clearfix - .pull-left Comments are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"),{ target: '_blank', tabindex: -1 }} - .pull-right Attach files by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector', tabindex: -1 }. - - .note-form-actions - .buttons - = f.submit 'Save Comment', class: "btn btn-primary btn-save btn-grouped js-comment-button" - = link_to 'Cancel', "#", class: "btn btn-cancel note-edit-cancel" \ No newline at end of file diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml deleted file mode 100644 index 2ada6cb6700dd11ead463d53b154fa8327bf9ee7..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_form.html.haml +++ /dev/null @@ -1,24 +0,0 @@ -= form_for [@project.namespace.becomes(Namespace), @project, @note], remote: true, html: { :'data-type' => 'json', multipart: true, id: nil, class: "new_note js-new-note-form common-note-form gfm-form" }, authenticity_token: true do |f| - = note_target_fields(@note) - = f.hidden_field :commit_id - = f.hidden_field :line_code - = f.hidden_field :noteable_id - = f.hidden_field :noteable_type - - = render layout: 'projects/md_preview', locals: { preview_class: "note-text" } do - = render 'projects/zen', f: f, attr: :note, - classes: 'note_text js-note-text' - - .comment-hints.clearfix - .pull-left Comments are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"),{ target: '_blank', tabindex: -1 }} - .pull-right Attach files by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector', tabindex: -1 }. - .error-alert - - .note-form-actions - .buttons - = f.submit 'Add Comment', class: "btn comment-btn btn-grouped js-comment-button" - = yield(:note_actions) - %a.btn.grouped.js-close-discussion-note-form Cancel - -:javascript - window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}"; diff --git a/app/views/projects/notes/_form_errors.html.haml b/app/views/projects/notes/_form_errors.html.haml deleted file mode 100644 index 0b68bf243f058fea0dded49389a94c97ea91e002..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_form_errors.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -.error-message.js-errors - - note.errors.full_messages.each do |msg| - %div= msg diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml deleted file mode 100644 index 0728f8fa42b878105376b18ad868cb4a687ba69e..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_note.html.haml +++ /dev/null @@ -1,71 +0,0 @@ -%li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)], data: { discussion: note.discussion_id } } - .timeline-entry-inner - .timeline-icon - - if note.system - %span.fa.fa-circle - - else - = link_to user_path(note.author) do - = image_tag avatar_icon(note.author_email), class: "avatar s40", alt: '' - .timeline-content - .note-header - .note-actions - = link_to "##{dom_id(note)}", name: dom_id(note) do - %i.fa.fa-link - Link here -   - - if can?(current_user, :admin_note, note) && note.editable? - = link_to "#", title: "Edit comment", class: "js-note-edit" do - %i.fa.fa-pencil-square-o - Edit -   - = link_to namespace_project_note_path(@project.namespace, @project, note), title: "Remove comment", method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: "danger js-note-delete" do - %i.fa.fa-trash-o.cred - Remove - - if note.system - = link_to user_path(note.author) do - = image_tag avatar_icon(note.author_email), class: "avatar s16", alt: '' - = link_to_member(@project, note.author, avatar: false) - %span.author-username - = '@' + note.author.username - %span.note-last-update - = note_timestamp(note) - - - if note.superceded?(@notes) - - if note.upvote? - %span.vote.upvote.label.label-gray.strikethrough - %i.fa.fa-thumbs-up - \+1 - - if note.downvote? - %span.vote.downvote.label.label-gray.strikethrough - %i.fa.fa-thumbs-down - \-1 - - else - - if note.upvote? - %span.vote.upvote.label.label-success - %i.fa.fa-thumbs-up - \+1 - - if note.downvote? - %span.vote.downvote.label.label-danger - %i.fa.fa-thumbs-down - \-1 - - - .note-body - .note-text - = preserve do - = markdown(note.note, {no_header_anchors: true}) - = render 'projects/notes/edit_form', note: note - - - if note.attachment.url - .note-attachment - - if note.attachment.image? - = link_to note.attachment.url, target: '_blank' do - = image_tag note.attachment.url, class: 'note-image-attach' - .attachment - = link_to note.attachment.url, target: "_blank" do - %i.fa.fa-paperclip - = note.attachment_identifier - = link_to delete_attachment_namespace_project_note_path(@project.namespace, @project, note), - title: "Delete this attachment", method: :delete, remote: true, data: { confirm: 'Are you sure you want to remove the attachment?' }, class: "danger js-note-attachment-delete" do - %i.fa.fa-trash-o.cred - .clear diff --git a/app/views/projects/notes/_notes.html.haml b/app/views/projects/notes/_notes.html.haml deleted file mode 100644 index ca60dd239b234033e6106d5466ce86689ba83d52..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_notes.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -- if @discussions.present? - - @discussions.each do |discussion_notes| - - note = discussion_notes.first - - if note_for_main_target?(note) - = render discussion_notes - - else - = render 'projects/notes/discussion', discussion_notes: discussion_notes -- else - - @notes.each do |note| - - next unless note.author - = render note diff --git a/app/views/projects/notes/_notes_with_form.html.haml b/app/views/projects/notes/_notes_with_form.html.haml deleted file mode 100644 index 813e37276bdd8ec5fda2bad1f678a64069bedb25..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/_notes_with_form.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -%ul#notes-list.notes.main-notes-list.timeline - = render "projects/notes/notes" -.js-notes-busy - -.js-main-target-form -- if can? current_user, :write_note, @project - = render "projects/notes/form" - -:javascript - new Notes("#{namespace_project_notes_path(namespace_id: @project.namespace, target_id: @noteable.id, target_type: @noteable.class.name.underscore)}", #{@notes.map(&:id).to_json}, #{Time.now.to_i}) diff --git a/app/views/projects/notes/discussions/_active.html.haml b/app/views/projects/notes/discussions/_active.html.haml deleted file mode 100644 index 7c6f72431730a42361fa2225df776aaed3e4bf68..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/discussions/_active.html.haml +++ /dev/null @@ -1,20 +0,0 @@ -- note = discussion_notes.first -.discussion.js-toggle-container{ class: note.discussion_id } - .discussion-header - .discussion-actions - = link_to "#", class: "js-toggle-button" do - %i.fa.fa-chevron-up - Show/hide discussion - %div - = link_to_member(@project, note.author, avatar: false) - started a discussion - = link_to diffs_namespace_project_merge_request_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) do - %strong on the diff - .last-update.hide.js-toggle-content - - last_note = discussion_notes.last - last updated by - = link_to_member(@project, last_note.author, avatar: false) - %span.discussion-last-update - #{time_ago_with_tooltip(last_note.updated_at, 'bottom', 'discussion_updated_ago')} - .discussion-body.js-toggle-content - = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note diff --git a/app/views/projects/notes/discussions/_commit.html.haml b/app/views/projects/notes/discussions/_commit.html.haml deleted file mode 100644 index 62609cfc1c8858d395a2e91b61c0921aaf0d7606..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/discussions/_commit.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -- note = discussion_notes.first -.discussion.js-toggle-container{ class: note.discussion_id } - .discussion-header - .discussion-actions - = link_to "#", class: "js-toggle-button" do - %i.fa.fa-chevron-up - Show/hide discussion - %div - = link_to_member(@project, note.author, avatar: false) - started a discussion on commit - = link_to(note.noteable.short_id, namespace_project_commit_path(note.project.namespace, note.project, note.noteable), class: 'monospace') - .last-update.hide.js-toggle-content - - last_note = discussion_notes.last - last updated by - = link_to_member(@project, last_note.author, avatar: false) - %span.discussion-last-update - #{time_ago_with_tooltip(last_note.updated_at, 'bottom', 'discussion_updated_ago')} - .discussion-body.js-toggle-content - - if note.for_diff_line? - = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note - - else - .panel.panel-default - .notes{ rel: discussion_notes.first.discussion_id } - = render discussion_notes - .discussion-reply-holder - = link_to_reply_diff(discussion_notes.first) - diff --git a/app/views/projects/notes/discussions/_diff.html.haml b/app/views/projects/notes/discussions/_diff.html.haml deleted file mode 100644 index 711aa39101b865a3c1008ba8b89c40b1d68f74e4..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/discussions/_diff.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -- diff = note.diff -- if diff - .diff-file - .diff-header - %span - - if diff.deleted_file - = diff.old_path - - else - = diff.new_path - - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode - %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" - .diff-content - %table - - note.truncated_diff_lines.each do |line| - - line_code = generate_line_code(note.file_path, line) - %tr.line_holder{ id: line_code } - - if line.type == "match" - %td.old_line= "..." - %td.new_line= "..." - %td.line_content.matched= line.text - - else - %td.old_line{class: line.type == "new" ? "new" : "old"} - = raw(line.type == "new" ? " " : line.old_pos) - %td.new_line{class: line.type == "new" ? "new" : "old"} - = raw(line.type == "old" ? " " : line.new_pos) - %td.line_content{class: "noteable_line #{line.type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text) - - - if line_code == note.line_code - = render "projects/notes/diff_notes_with_reply", notes: discussion_notes diff --git a/app/views/projects/notes/discussions/_outdated.html.haml b/app/views/projects/notes/discussions/_outdated.html.haml deleted file mode 100644 index 52a1d342f55059f6be65b5089027ec4335664be8..0000000000000000000000000000000000000000 --- a/app/views/projects/notes/discussions/_outdated.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -- note = discussion_notes.first -.discussion.js-toggle-container{ class: note.discussion_id } - .discussion-header - .discussion-actions - = link_to "#", class: "js-toggle-button" do - %i.fa.fa-chevron-down - Show/hide discussion - %div - = link_to_member(@project, note.author, avatar: false) - started a discussion on the - %strong outdated diff - %div - - last_note = discussion_notes.last - last updated by - = link_to_member(@project, last_note.author, avatar: false) - %span.discussion-last-update - #{time_ago_with_tooltip(last_note.updated_at, 'bottom', 'discussion_updated_ago')} - .discussion-body.js-toggle-content.hide - = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note diff --git a/app/views/projects/project_members/_group_members.html.haml b/app/views/projects/project_members/_group_members.html.haml deleted file mode 100644 index 43e92437cf577e64163efd308ca0526e86c3f1ac..0000000000000000000000000000000000000000 --- a/app/views/projects/project_members/_group_members.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -.panel.panel-default - .panel-heading - %strong #{@group.name} - group members - %small - (#{members.count}) - .panel-head-actions - = link_to group_group_members_path(@group), class: 'btn btn-sm' do - %i.fa.fa-pencil-square-o - Edit group members - %ul.well-list - - members.each do |member| - = render 'groups/group_members/group_member', member: member, show_controls: false - - if members.count > 20 - %li - and #{members.count - 20} more. For full list visit #{link_to 'group members page', group_group_members_path(@group)} diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml deleted file mode 100644 index d708b01a114873fda0195d43cc4cf09d29a45018..0000000000000000000000000000000000000000 --- a/app/views/projects/project_members/_new_project_member.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -= form_for @project_member, as: :project_member, url: namespace_project_project_members_path(@project.namespace, @project), html: { class: 'form-horizontal users-project-form' } do |f| - .form-group - = f.label :user_ids, "People", class: 'control-label' - .col-sm-10 - = users_select_tag(:user_ids, multiple: true, class: 'input-large', scope: :all, email_user: true) - .help-block - Search for existing users or invite new ones using their email address. - - .form-group - = f.label :access_level, "Project Access", class: 'control-label' - .col-sm-10 - = select_tag :access_level, options_for_select(ProjectMember.access_roles, @project_member.access_level), class: "project-access-select select2" - .help-block - Read more about role permissions - %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" - - .form-actions - = f.submit 'Add users to project', class: "btn btn-create" diff --git a/app/views/projects/project_members/_project_member.html.haml b/app/views/projects/project_members/_project_member.html.haml deleted file mode 100644 index 635e4d7094173682031c0eb340509efae6dd819d..0000000000000000000000000000000000000000 --- a/app/views/projects/project_members/_project_member.html.haml +++ /dev/null @@ -1,53 +0,0 @@ -- user = member.user -- return unless user || member.invite? - -%li{class: "#{dom_class(member)} js-toggle-container project_member_row access-#{member.human_access.downcase}", id: dom_id(member)} - %span.list-item-name - - if member.user - = image_tag avatar_icon(user.email, 16), class: "avatar s16", alt: '' - %strong - = link_to user.name, user_path(user) - %span.cgray= user.username - - if user == current_user - %span.label.label-success It's you - - if user.blocked? - %label.label.label-danger - %strong Blocked - - else - = image_tag avatar_icon(member.invite_email, 16), class: "avatar s16", alt: '' - %strong - = member.invite_email - %span.cgray - invited - - if member.created_by - by - = link_to member.created_by.name, user_path(member.created_by) - = time_ago_with_tooltip(member.created_at) - - - if current_user_can_admin_project - = link_to resend_invite_namespace_project_project_member_path(@project.namespace, @project, member), method: :post, class: "btn-xs btn", title: 'Resend invite' do - Resend invite - - - if current_user_can_admin_project - - unless @project.personal? && user == current_user - .pull-right - %strong= member.human_access - = button_tag class: "btn-xs btn js-toggle-button", - title: 'Edit access level', type: 'button' do - %i.fa.fa-pencil-square-o - -   - - if current_user == user - = link_to leave_namespace_project_project_members_path(@project.namespace, @project), data: { confirm: "Leave project?"}, method: :delete, class: "btn-xs btn btn-remove", title: 'Leave project' do - %i.fa.fa-minus.fa-inverse - - else - = link_to namespace_project_project_member_path(@project.namespace, @project, member), data: { confirm: remove_from_project_team_message(@project, member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from team' do - %i.fa.fa-minus.fa-inverse - - .edit-member.hide.js-toggle-content - %br - = form_for member, as: :project_member, url: namespace_project_project_member_path(@project.namespace, @project, member), remote: true do |f| - .prepend-top-10 - = f.select :access_level, options_for_select(ProjectMember.access_roles, member.access_level), {}, class: 'form-control' - .prepend-top-10 - = f.submit 'Save', class: 'btn btn-save' diff --git a/app/views/projects/project_members/_team.html.haml b/app/views/projects/project_members/_team.html.haml deleted file mode 100644 index 615c425e59ae2967a6ba90f5d7ff6ad8bd83103d..0000000000000000000000000000000000000000 --- a/app/views/projects/project_members/_team.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -- can_admin_project = can?(current_user, :admin_project, @project) - -.panel.panel-default.prepend-top-20 - .panel-heading - %strong #{@project.name} - project members - %small - (#{members.count}) - %ul.well-list - - members.each do |project_member| - = render 'project_member', member: project_member, current_user_can_admin_project: can_admin_project diff --git a/app/views/projects/project_members/import.html.haml b/app/views/projects/project_members/import.html.haml deleted file mode 100644 index 293754cd0c0fa180a5f80dec6fdb78738d88306a..0000000000000000000000000000000000000000 --- a/app/views/projects/project_members/import.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -%h3.page-title - Import members from another project -%p.light - Only project members will be imported. Group members will be skipped. -%hr -= form_tag apply_import_namespace_project_project_members_path(@project.namespace, @project), method: 'post', class: 'form-horizontal' do - .form-group - = label_tag :source_project_id, "Project", class: 'control-label' - .col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true) - - .form-actions - = button_tag 'Import project members', class: "btn btn-create" - = link_to "Cancel", namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-cancel" - diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml deleted file mode 100644 index 36a6f6a15547d9d05737d5ff08f475a198531dae..0000000000000000000000000000000000000000 --- a/app/views/projects/project_members/index.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -%h3.page-title - Users with access to this project - -%p.light - Read more about project permissions - %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" - -%hr - -.clearfix.js-toggle-container - = form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do - .form-group - = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input input-mn-300' } - = button_tag 'Search', class: 'btn' - - - if can?(current_user, :admin_project_member, @project) - %span.pull-right - = button_tag class: 'btn btn-new btn-grouped js-toggle-button', type: 'button' do - Add members - %i.fa.fa-chevron-down - = link_to import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do - Import members - - .js-toggle-content.hide.new-group-member-holder - = render "new_project_member" - -= render "team", members: @project_members - -- if @group - = render "group_members", members: @group_members - -:coffeescript - $('form.member-search-form').on 'submit', (event) -> - event.preventDefault() - Turbolinks.visit @.action + '?' + $(@).serialize() diff --git a/app/views/projects/project_members/update.js.haml b/app/views/projects/project_members/update.js.haml deleted file mode 100644 index 811b1858821c93518116a449322dc0b161954f77..0000000000000000000000000000000000000000 --- a/app/views/projects/project_members/update.js.haml +++ /dev/null @@ -1,3 +0,0 @@ -- can_admin_project = can?(current_user, :admin_project, @project) -:plain - $("##{dom_id(@project_member)}").replaceWith('#{escape_javascript(render("project_member", member: @project_member, current_user_can_admin_project: can_admin_project))}'); diff --git a/app/views/projects/protected_branches/_branches_list.html.haml b/app/views/projects/protected_branches/_branches_list.html.haml deleted file mode 100644 index bb49f4de8736ce2422f605b09c67824ac4ef0040..0000000000000000000000000000000000000000 --- a/app/views/projects/protected_branches/_branches_list.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -- unless @branches.empty? - %br - %h4 Already Protected: - %table.table.protected-branches-list - %thead - %tr.no-border - %th Branch - %th Developers can push - %th Last commit - %th - - %tbody - - @branches.each do |branch| - - @url = namespace_project_protected_branch_path(@project.namespace, @project, branch) - %tr - %td - = link_to namespace_project_commits_path(@project.namespace, @project, branch.name) do - %strong= branch.name - - if @project.root_ref?(branch.name) - %span.label.label-info default - %td - = check_box_tag "developers_can_push", branch.id, branch.developers_can_push, "data-url" => @url - %td - - if commit = branch.commit - = link_to namespace_project_commit_path(@project.namespace, @project, commit.id), class: 'commit_short_id' do - = commit.short_id - · - #{time_ago_with_tooltip(commit.committed_date)} - - else - (branch was removed from repository) - %td - .pull-right - - if can? current_user, :admin_project, @project - = link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-remove btn-sm" diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml deleted file mode 100644 index a3464c0e5e183d623abb99c5372b588349c9aee3..0000000000000000000000000000000000000000 --- a/app/views/projects/protected_branches/index.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -%h3.page-title Protected branches -%p.light Keep stable branches secure and force developers to use Merge Requests -%hr - -.well.append-bottom-20 - %p Protected branches are designed to - %ul - %li prevent pushes from everybody except #{link_to "masters", help_page_path("permissions", "permissions"), class: "vlink"} - %li prevent anyone from force pushing to the branch - %li prevent anyone from deleting the branch - %p Read more about #{link_to "project permissions", help_page_path("permissions", "permissions"), class: "underlined-link"} - -- if can? current_user, :admin_project, @project - = form_for [@project.namespace.becomes(Namespace), @project, @protected_branch], html: { class: 'form-horizontal' } do |f| - -if @protected_branch.errors.any? - .alert.alert-danger - %ul - - @protected_branch.errors.full_messages.each do |msg| - %li= msg - - .form-group - = f.label :name, "Branch", class: 'control-label' - .col-sm-10 - = f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , {include_blank: "Select branch"}, {class: "select2"}) - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :developers_can_push do - = f.check_box :developers_can_push - %strong Developers can push - .help-block Allow developers to push to this branch - .form-actions - = f.submit 'Protect', class: "btn-create btn" -= render 'branches_list' - diff --git a/app/views/projects/refs/logs_tree.js.haml b/app/views/projects/refs/logs_tree.js.haml deleted file mode 100644 index 35c15cf3a9ed70f327a1779e104f45c790f13b15..0000000000000000000000000000000000000000 --- a/app/views/projects/refs/logs_tree.js.haml +++ /dev/null @@ -1,19 +0,0 @@ -- @logs.each do |content_data| - - file_name = content_data[:file_name] - - commit = content_data[:commit] - - next unless commit - - :plain - var row = $("table.table_#{@hex_path} tr.file_#{hexdigest(file_name)}"); - row.find("td.tree_time_ago").html('#{escape_javascript time_ago_with_tooltip(commit.committed_date)}'); - row.find("td.tree_commit").html('#{escape_javascript render("projects/tree/tree_commit_column", commit: commit)}'); - -- if @logs.present? - :plain - var current_url = location.href.replace(/\/?$/, '/'); - var log_url = '#{namespace_project_tree_url(@project.namespace, @project, tree_join(@ref, @path || '/'))}'.replace(/\/?$/, '/'); - if(current_url == log_url) { - // Load 10 more commit log for each file in tree - // if we still on the same page - ajaxGet('#{logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '', offset: (@offset + @limit))}'); - } diff --git a/app/views/projects/repositories/_download_archive.html.haml b/app/views/projects/repositories/_download_archive.html.haml deleted file mode 100644 index b9486a9b49265c92771b58c529b26fd9f51cb4de..0000000000000000000000000000000000000000 --- a/app/views/projects/repositories/_download_archive.html.haml +++ /dev/null @@ -1,37 +0,0 @@ -- ref = ref || nil -- btn_class = btn_class || '' -- split_button = split_button || false -- if split_button == true - %span.btn-group{class: btn_class} - = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), class: 'btn col-xs-10', rel: 'nofollow' do - %i.fa.fa-download - %span Download zip - %a.col-xs-2.btn.dropdown-toggle{ 'data-toggle' => 'dropdown' } - %span.caret - %span.sr-only - Select Archive Format - %ul.col-xs-10.dropdown-menu{ role: 'menu' } - %li - = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), rel: 'nofollow' do - %i.fa.fa-download - %span Download zip - %li - = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'tar.gz'), rel: 'nofollow' do - %i.fa.fa-download - %span Download tar.gz - %li - = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'tar.bz2'), rel: 'nofollow' do - %i.fa.fa-download - %span Download tar.bz2 - %li - = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'tar'), rel: 'nofollow' do - %i.fa.fa-download - %span Download tar -- else - %span.btn-group{class: btn_class} - = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), class: 'btn', rel: 'nofollow' do - %i.fa.fa-download - %span zip - = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'tar.gz'), class: 'btn', rel: 'nofollow' do - %i.fa.fa-download - %span tar.gz diff --git a/app/views/projects/repositories/_feed.html.haml b/app/views/projects/repositories/_feed.html.haml deleted file mode 100644 index f3526ad0747a8dbe31117f5e0dd7308efc9c3db1..0000000000000000000000000000000000000000 --- a/app/views/projects/repositories/_feed.html.haml +++ /dev/null @@ -1,18 +0,0 @@ -- commit = update -%tr - %td - = link_to namespace_project_commits_path(@project.namespace, @project, commit.head.name) do - %strong - = commit.head.name - - if @project.root_ref?(commit.head.name) - %span.label default - - %td - %div - = link_to namespace_project_commits_path(@project.namespace, @project, commit.id) do - %code= commit.short_id - = image_tag avatar_icon(commit.author_email), class: "", width: 16, alt: '' - = gfm escape_once(truncate(commit.title, length: 40)) - %td - %span.pull-right.cgray - = time_ago_with_tooltip(commit.committed_date) diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml deleted file mode 100644 index ce6b7a0737a8c0fa344687710d8f2d2f0cae0666..0000000000000000000000000000000000000000 --- a/app/views/projects/services/_form.html.haml +++ /dev/null @@ -1,106 +0,0 @@ -%h3.page-title - = @service.title - = boolean_to_icon @service.activated? - -%p= @service.description - -.back-link - = link_to namespace_project_services_path(@project.namespace, @project) do - ← to services - -%hr - -= form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |f| - - if @service.errors.any? - .alert.alert-danger - %ul - - @service.errors.full_messages.each do |msg| - %li= msg - - - if @service.help.present? - .well - = preserve do - = markdown @service.help - - .form-group - = f.label :active, "Active", class: "control-label" - .col-sm-10 - = f.check_box :active - - - if @service.supported_events.length > 1 - .form-group - = f.label :url, "Trigger", class: 'control-label' - .col-sm-10 - - if @service.supported_events.include?("push") - %div - = f.check_box :push_events, class: 'pull-left' - .prepend-left-20 - = f.label :push_events, class: 'list-label' do - %strong Push events - %p.light - This url will be triggered by a push to the repository - - if @service.supported_events.include?("tag_push") - %div - = f.check_box :tag_push_events, class: 'pull-left' - .prepend-left-20 - = f.label :tag_push_events, class: 'list-label' do - %strong Tag push events - %p.light - This url will be triggered when a new tag is pushed to the repository - - if @service.supported_events.include?("note") - %div - = f.check_box :note_events, class: 'pull-left' - .prepend-left-20 - = f.label :note_events, class: 'list-label' do - %strong Comments - %p.light - This url will be triggered when someone adds a comment - - if @service.supported_events.include?("issue") - %div - = f.check_box :issues_events, class: 'pull-left' - .prepend-left-20 - = f.label :issues_events, class: 'list-label' do - %strong Issues events - %p.light - This url will be triggered when an issue is created - - if @service.supported_events.include?("merge_request") - %div - = f.check_box :merge_requests_events, class: 'pull-left' - .prepend-left-20 - = f.label :merge_requests_events, class: 'list-label' do - %strong Merge Request events - %p.light - This url will be triggered when a merge request is created - - - @service.fields.each do |field| - - name = field[:name] - - title = field[:title] || name.humanize - - value = service_field_value(field[:type], @service.send(name)) - - type = field[:type] - - placeholder = field[:placeholder] - - choices = field[:choices] - - default_choice = field[:default_choice] - - help = field[:help] - - .form-group - = f.label name, title, class: "control-label" - .col-sm-10 - - if type == 'text' - = f.text_field name, class: "form-control", placeholder: placeholder - - elsif type == 'textarea' - = f.text_area name, rows: 5, class: "form-control", placeholder: placeholder - - elsif type == 'checkbox' - = f.check_box name - - elsif type == 'select' - = f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" } - - elsif type == 'password' - = f.password_field name, placeholder: value, class: 'form-control' - - if help - %span.help-block= help - - .form-actions - = f.submit 'Save', class: 'btn btn-save' -   - - if @service.valid? && @service.activated? - - disabled = @service.can_test? ? '':'disabled' - = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: "btn #{disabled}" diff --git a/app/views/projects/services/edit.html.haml b/app/views/projects/services/edit.html.haml deleted file mode 100644 index bcc5832792fea10b70d29a9fb15633f06e001dd0..0000000000000000000000000000000000000000 --- a/app/views/projects/services/edit.html.haml +++ /dev/null @@ -1 +0,0 @@ -= render 'form' diff --git a/app/views/projects/services/index.html.haml b/app/views/projects/services/index.html.haml deleted file mode 100644 index 0d3ccb6bb839e7306e5b9409fee7e309d11eea3e..0000000000000000000000000000000000000000 --- a/app/views/projects/services/index.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -%h3.page-title Project services -%p.light Project services allow you to integrate GitLab with other applications - -%table.table - %thead - %tr - %th - %th Service - %th Description - %th Last edit - - @services.sort_by(&:title).each do |service| - %tr - %td - = boolean_to_icon service.activated? - %td - = link_to edit_namespace_project_service_path(@project.namespace, @project, service.to_param) do - %strong= service.title - %td - = service.description - %td.light - = time_ago_in_words service.updated_at - ago diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml deleted file mode 100644 index 4464c51744aa77199b331d8effc9293ffbc8027a..0000000000000000000000000000000000000000 --- a/app/views/projects/show.html.haml +++ /dev/null @@ -1,108 +0,0 @@ -- if current_user && can?(current_user, :download_code, @project) - = render 'shared/no_ssh' - = render 'shared/no_password' - -= render "home_panel" - -%ul.nav.nav-tabs - %li.active - = link_to '#tab-activity', 'data-toggle' => 'tab' do - Activity - - if @repository.readme - %li - = link_to '#tab-readme', 'data-toggle' => 'tab' do - Readme - - if @repository.changelog - %li - = link_to changelog_url(@project) do - Changelog - - if @repository.contribution_guide - %li - = link_to contribution_guide_url(@project) do - Contribution guide - - if @repository.license - %li - = link_to license_url(@project) do - License - - .project-home-links - - unless @project.empty_repo? - = link_to pluralize(number_with_delimiter(@repository.commit_count), 'commit'), namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) - = link_to pluralize(number_with_delimiter(@repository.branch_names.count), 'branch'), namespace_project_branches_path(@project.namespace, @project) - = link_to pluralize(number_with_delimiter(@repository.tag_names.count), 'tag'), namespace_project_tags_path(@project.namespace, @project) - %span.light.prepend-left-20= repository_size - -.tab-content - .tab-pane.active#tab-activity - .row - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left - %section.col-md-9 - = render "events/event_last_push", event: @last_push - = render 'shared/event_filter' - .content_list - = spinner - %aside.col-md-3.project-side - .clearfix - - if @project.archived? - .alert.alert-warning - %h4 - %i.fa.fa-exclamation-triangle - Archived project! - %p Repository is read-only - - - if @project.forked_from_project - .well - %i.fa.fa-code-fork.project-fork-icon - Forked from: - %br - = link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project) - - - unless @project.empty_repo? - = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: @ref || @repository.root_ref), class: 'btn btn-block' do - %i.fa.fa-exchange - Compare code - - - if can?(current_user, :download_code, @project) - = render 'projects/repositories/download_archive', split_button: true, btn_class: 'btn-block' - - - if version = @repository.version - - detail_url = changelog_url(@project) || version_url(@project) - = link_to detail_url, class: 'btn btn-block' do - %i.fa.fa-file-text-o - Version: - %span.count - = @repository.blob_by_oid(version.id).data - - .prepend-top-10.append-bottom-10 - %p - %span.light Created on - #{@project.created_at.stamp('Aug 22, 2013')} - %p - %span.light Owned by #{@project.group ? "the" : nil} - - if @project.group - #{link_to @project.group.name, @project.group} group - - else - #{link_to @project.owner_name, @project.owner} - - - .prepend-top-10 - - @project.ci_services.each do |ci_service| - - if ci_service.active? && ci_service.respond_to?(:builds_path) - %hr - - if ci_service.respond_to?(:status_img_path) - = link_to ci_service.builds_path, :'data-no-turbolink' => 'data-no-turbolink' do - = image_tag ci_service.status_img_path, alt: "build status" - - else - %span.light CI provided by - = link_to ci_service.title, ci_service.builds_path, :'data-no-turbolink' => 'data-no-turbolink' - - - if readme = @repository.readme - .tab-pane#tab-readme - %article.readme-holder#README - = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@repository.root_ref, readme.name)) do - %h4.readme-file-title - %i.fa.fa-file - = readme.name - .wiki - = render_readme(readme) diff --git a/app/views/projects/snippets/_snippet.html.haml b/app/views/projects/snippets/_snippet.html.haml deleted file mode 100644 index b2c35edc44c653e011712dbbb54e26040affeb9a..0000000000000000000000000000000000000000 --- a/app/views/projects/snippets/_snippet.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -%li - %h4.snippet-title - = link_to reliable_snippet_path(snippet) do - = truncate(snippet.title, length: 60) - %span.cgray.monospace.tiny.pull-right - = snippet.file_name - - .snippet-info - = "##{snippet.id}" - %span - by - = image_tag avatar_icon(snippet.author_email), class: "avatar avatar-inline s16" - = snippet.author_name - %span.light - #{time_ago_with_tooltip(snippet.created_at)} diff --git a/app/views/projects/snippets/edit.html.haml b/app/views/projects/snippets/edit.html.haml deleted file mode 100644 index 2d4d5d030ab3ec37c7601b4dc9d114bfec25621f..0000000000000000000000000000000000000000 --- a/app/views/projects/snippets/edit.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h3.page-title - Edit snippet -%hr -= render "shared/snippets/form", url: namespace_project_snippet_path(@project.namespace, @project, @snippet) diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml deleted file mode 100644 index e2d8ec673a17fe3f2e6ced456fbf3d9b5da3ba22..0000000000000000000000000000000000000000 --- a/app/views/projects/snippets/index.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -%h3.page-title - Snippets - - if can? current_user, :write_project_snippet, @project - = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: "btn btn-new pull-right", title: "New Snippet" do - Add new snippet - -%p.light - Share code pastes with others out of git repository - -%hr -%ul.bordered-list - = render partial: "projects/snippets/snippet", collection: @snippets - - if @snippets.empty? - %li - .nothing-here-block Nothing here. diff --git a/app/views/projects/snippets/new.html.haml b/app/views/projects/snippets/new.html.haml deleted file mode 100644 index bb659dba0cf1cb21504f6796f835193055565305..0000000000000000000000000000000000000000 --- a/app/views/projects/snippets/new.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h3.page-title - New snippet -%hr -= render "shared/snippets/form", url: namespace_project_snippets_path(@project.namespace, @project, @snippet) diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml deleted file mode 100644 index d19689a1056213a16988e15c975c09e4c2e4d888..0000000000000000000000000000000000000000 --- a/app/views/projects/snippets/show.html.haml +++ /dev/null @@ -1,37 +0,0 @@ -%h3.page-title - = @snippet.title - - .pull-right - = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: "btn btn-new", title: "New Snippet" do - Add new snippet - -%hr - -.append-bottom-20 - .pull-right - = "##{@snippet.id}" - %span.light - by - = link_to user_path(@snippet.author) do - = image_tag avatar_icon(@snippet.author_email), class: "avatar avatar-inline s16" - = @snippet.author_name - - .back-link - = link_to namespace_project_snippets_path(@project.namespace, @project) do - ← project snippets - -.file-holder - .file-title - %i.fa.fa-file - %strong - = @snippet.file_name - .file-actions - .btn-group - - if can?(current_user, :modify_project_snippet, @snippet) - = link_to "edit", edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", title: 'Edit Snippet' - = link_to "raw", raw_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", target: "_blank" - - if can?(current_user, :admin_project_snippet, @snippet) - = link_to "remove", namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-sm btn-remove", title: 'Delete Snippet' - = render 'shared/snippets/blob' - -%div#notes= render "projects/notes/notes_with_form" diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml deleted file mode 100644 index 28ad272322ff3c1ada704fec7a8b82da175c1f66..0000000000000000000000000000000000000000 --- a/app/views/projects/tags/_tag.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -- commit = @repository.commit(tag.target) -%li - %h4 - = link_to namespace_project_commits_path(@project.namespace, @project, tag.name), class: "" do - %i.fa.fa-tag - = tag.name - - if tag.message.present? -   - = strip_gpg_signature(tag.message) - .pull-right - - if can? current_user, :download_code, @project - = render 'projects/repositories/download_archive', ref: tag.name, btn_class: 'btn-grouped btn-group-xs' - - if can?(current_user, :admin_project, @project) - = link_to namespace_project_tag_path(@project.namespace, @project, tag.name), class: 'btn btn-xs btn-remove remove-row grouped', method: :delete, data: { confirm: 'Removed tag cannot be restored. Are you sure?'}, remote: true do - %i.fa.fa-trash-o - - - if commit - %ul.list-unstyled - = render 'projects/commits/inline_commit', commit: commit, project: @project - - else - %p - Cant find HEAD commit for this tag diff --git a/app/views/projects/tags/destroy.js.haml b/app/views/projects/tags/destroy.js.haml deleted file mode 100644 index ada6710f940638e963947e871f37fd2e22268b41..0000000000000000000000000000000000000000 --- a/app/views/projects/tags/destroy.js.haml +++ /dev/null @@ -1,3 +0,0 @@ -$('.js-totaltags-count').html("#{@repository.tags.size}") -- if @repository.tags.size == 0 - $('.tags').load(document.URL + ' .nothing-here-block').hide().fadeIn(1000) diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml deleted file mode 100644 index f1bc2bc9a2b23aa8cfc5526a610b7b4c59bb0c6f..0000000000000000000000000000000000000000 --- a/app/views/projects/tags/index.html.haml +++ /dev/null @@ -1,30 +0,0 @@ -= render "projects/commits/head" - -%h3.page-title - Git Tags - - if can? current_user, :push_code, @project - .pull-right - = link_to new_namespace_project_tag_path(@project.namespace, @project), class: 'btn btn-create new-tag-btn' do - %i.fa.fa-add-sign - New tag - -%p.light - Tags give the ability to mark specific points in history as being important -%hr - -.tags - - unless @tags.empty? - %ul.bordered-list - - @tags.each do |tag| - = render 'tag', tag: @repository.find_tag(tag) - - = paginate @tags, theme: 'gitlab' - - - else - .nothing-here-block - Repository has no tags yet. - %br - %small - Use git tag command to add a new one: - %br - %span.monospace git tag -a v1.4 -m 'version 1.4' diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml deleted file mode 100644 index 655044438d50a412085d3e9e2ee351fefebb8ccb..0000000000000000000000000000000000000000 --- a/app/views/projects/tags/new.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -- if @error - .alert.alert-danger - %button{ type: "button", class: "close", "data-dismiss" => "alert"} × - = @error -%h3.page-title - %i.fa.fa-code-fork - New tag -= form_tag namespace_project_tags_path, method: :post, id: "new-tag-form", class: "form-horizontal" do - .form-group - = label_tag :tag_name, 'Name for new tag', class: 'control-label' - .col-sm-10 - = text_field_tag :tag_name, params[:tag_name], placeholder: 'v3.0.1', required: true, tabindex: 1, class: 'form-control' - .form-group - = label_tag :ref, 'Create from', class: 'control-label' - .col-sm-10 - = text_field_tag :ref, params[:ref], placeholder: 'master', required: true, tabindex: 2, class: 'form-control' - .light Branch name or commit SHA - .form-group - = label_tag :message, 'Message', class: 'control-label' - .col-sm-10 - = text_field_tag :message, nil, placeholder: 'Enter message.', required: false, tabindex: 3, class: 'form-control' - .light (Optional) Entering a message will create an annotated tag. - .form-actions - = button_tag 'Create tag', class: 'btn btn-create', tabindex: 3 - = link_to 'Cancel', namespace_project_tags_path(@project.namespace, @project), class: 'btn btn-cancel' - -:javascript - disableButtonIfAnyEmptyField($("#new-tag-form"), ".form-control", ".btn-create"); - var availableTags = #{@project.repository.ref_names.to_json}; - - $("#ref").autocomplete({ - source: availableTags, - minLength: 1 - }); diff --git a/app/views/projects/transfer.js.haml b/app/views/projects/transfer.js.haml deleted file mode 100644 index 17b9fecfeb162f8f3ac88523a7fbe336c4d46516..0000000000000000000000000000000000000000 --- a/app/views/projects/transfer.js.haml +++ /dev/null @@ -1,2 +0,0 @@ -:plain - location.href = "#{edit_namespace_project_path(@project.namespace, @project)}"; diff --git a/app/views/projects/tree/_blob_item.html.haml b/app/views/projects/tree/_blob_item.html.haml deleted file mode 100644 index 02ecbade219250ceaf038830c7f9da2361a5baba..0000000000000000000000000000000000000000 --- a/app/views/projects/tree/_blob_item.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -%tr{ class: "tree-item #{tree_hex_class(blob_item)}" } - %td.tree-item-file-name - = tree_icon(type, blob_item.mode, blob_item.name) - %span.str-truncated - = link_to blob_item.name, namespace_project_blob_path(@project.namespace, @project, tree_join(@id || @commit.id, blob_item.name)) - %td.tree_time_ago.cgray - = render 'spinner' - %td.hidden-xs.tree_commit diff --git a/app/views/projects/tree/_readme.html.haml b/app/views/projects/tree/_readme.html.haml deleted file mode 100644 index f082d71186558744fc0eba13427e81659c39c845..0000000000000000000000000000000000000000 --- a/app/views/projects/tree/_readme.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%article.readme-holder#README - = link_to '#README' do - %h4.readme-file-title - %i.fa.fa-file - = readme.name - .wiki - = render_readme(readme) diff --git a/app/views/projects/tree/_spinner.html.haml b/app/views/projects/tree/_spinner.html.haml deleted file mode 100644 index b47ad0f41e48d63a4ca2ba91d684729b4b47b14d..0000000000000000000000000000000000000000 --- a/app/views/projects/tree/_spinner.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%span.log_loading.hide - %i.fa.fa-spinner.fa-spin - Loading commit data... diff --git a/app/views/projects/tree/_submodule_item.html.haml b/app/views/projects/tree/_submodule_item.html.haml deleted file mode 100644 index 2b5f671c09ec5e4a1e268ecaa20f1578119c650d..0000000000000000000000000000000000000000 --- a/app/views/projects/tree/_submodule_item.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%tr{ class: "tree-item" } - %td.tree-item-file-name - %i.fa.fa-archive.fa-fw - = submodule_link(submodule_item, @ref) - %td - %td.hidden-xs diff --git a/app/views/projects/tree/_tree.html.haml b/app/views/projects/tree/_tree.html.haml deleted file mode 100644 index d304690d162778ef77965d48cc3739014c69adf5..0000000000000000000000000000000000000000 --- a/app/views/projects/tree/_tree.html.haml +++ /dev/null @@ -1,53 +0,0 @@ -%ul.breadcrumb.repo-breadcrumb - %li - = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do - = @project.path - - tree_breadcrumbs(tree, 6) do |title, path| - %li - - if path - = link_to truncate(title, length: 40), namespace_project_tree_path(@project.namespace, @project, path) - - else - = link_to title, '#' - - if current_user && can_push_branch?(@project, @ref) - %li - = link_to namespace_project_new_blob_path(@project.namespace, @project, @id), title: 'New file', id: 'new-file-link' do - %small - %i.fa.fa-plus - -%div#tree-content-holder.tree-content-holder - %table#tree-slider{class: "table_#{@hex_path} tree-table" } - %thead - %tr - %th Name - %th Last Update - %th.hidden-xs - .pull-left Last Commit - .last-commit.hidden-sm.pull-left -   - %i.fa.fa-angle-right -   - %small.light - = link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit) - – - = truncate(@commit.title, length: 50) - = link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), class: 'pull-right' - - - if @path.present? - %tr.tree-item - %td.tree-item-file-name - = link_to "..", namespace_project_tree_path(@project.namespace, @project, up_dir_path), class: 'prepend-left-10' - %td - %td.hidden-xs - - = render_tree(tree) - - - if tree.readme - = render "projects/tree/readme", readme: tree.readme - -%div.tree_progress - -:javascript - // Load last commit log for each file in tree - $('#tree-slider').waitForImages(function() { - ajaxGet('#{@logs_path}'); - }); diff --git a/app/views/projects/tree/_tree_commit_column.html.haml b/app/views/projects/tree/_tree_commit_column.html.haml deleted file mode 100644 index 50521264a611c386a9813fb6767d9dca1b4e7f54..0000000000000000000000000000000000000000 --- a/app/views/projects/tree/_tree_commit_column.html.haml +++ /dev/null @@ -1,3 +0,0 @@ -%span.str-truncated - %span.tree_author= commit_author_link(commit, avatar: true, size: 16) - = link_to_gfm commit.title, namespace_project_commit_path(@project.namespace, @project, commit.id), class: "tree-commit-link" diff --git a/app/views/projects/tree/_tree_item.html.haml b/app/views/projects/tree/_tree_item.html.haml deleted file mode 100644 index e87138bf9800bd7d4349d4b450a6dfb3af741353..0000000000000000000000000000000000000000 --- a/app/views/projects/tree/_tree_item.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -%tr{ class: "tree-item #{tree_hex_class(tree_item)}" } - %td.tree-item-file-name - = tree_icon(type, tree_item.mode, tree_item.name) - %span.str-truncated - - path = flatten_tree(tree_item) - = link_to path, namespace_project_tree_path(@project.namespace, @project, tree_join(@id || @commit.id, path)) - %td.tree_time_ago.cgray - = render 'spinner' - %td.hidden-xs.tree_commit diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml deleted file mode 100644 index feca145369752b8ad9e3758288dd7a33986d1e83..0000000000000000000000000000000000000000 --- a/app/views/projects/tree/show.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -.tree-ref-holder - = render 'shared/ref_switcher', destination: 'tree', path: @path - -- if can? current_user, :download_code, @project - .tree-download-holder - = render 'projects/repositories/download_archive', ref: @ref, btn_class: 'btn-group-sm pull-right hidden-xs hidden-sm', split_button: true - -#tree-holder.tree-holder.clearfix - = render "tree", tree: @tree diff --git a/app/views/projects/update.js.haml b/app/views/projects/update.js.haml deleted file mode 100644 index 4f3f4cab8d5c7b8df6afbfc79d7715fcd963ca4c..0000000000000000000000000000000000000000 --- a/app/views/projects/update.js.haml +++ /dev/null @@ -1,9 +0,0 @@ -- if @project.valid? - :plain - location.href = "#{edit_namespace_project_path(@project.namespace, @project)}"; -- else - :plain - $(".project-edit-errors").html("#{escape_javascript(render('errors'))}"); - $('.save-project-loader').hide(); - $('.project-edit-container').show(); - $('.project-edit-content .btn-save').enableButton(); diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml deleted file mode 100644 index 9fbfa0b1aebcc1adba1eb1dfc6c06d06534ca945..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/_form.html.haml +++ /dev/null @@ -1,46 +0,0 @@ -= form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal wiki-form gfm-form' } do |f| - -if @page.errors.any? - #error_explanation - .alert.alert-danger - - @page.errors.full_messages.each do |msg| - %p= msg - - = f.hidden_field :title, value: @page.title - .form-group - = f.label :format, class: 'control-label' - .col-sm-10 - = f.select :format, options_for_select(ProjectWiki::MARKUPS, {selected: @page.format}), {}, class: "form-control" - - .row - .col-sm-2 - .col-sm-10 - %p.cgray - To link to a (new) page you can just type - %code [Link Title](page-slug) - \. - - .form-group.wiki-content - = f.label :content, class: 'control-label' - .col-sm-10 - = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do - = render 'projects/zen', f: f, attr: :content, classes: 'description form-control' - .col-sm-12.hint - .pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'} - .pull-right Attach files by dragging & dropping or #{link_to "selecting them", '#', class: 'markdown-selector' }. - - .clearfix - .error-alert - .form-group - = f.label :commit_message, class: 'control-label' - .col-sm-10= f.text_field :message, class: 'form-control', rows: 18 - - .form-actions - - if @page && @page.persisted? - = f.submit 'Save changes', class: "btn-save btn" - = link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, @page), class: "btn btn-cancel" - - else - = f.submit 'Create page', class: "btn-create btn" - = link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, :home), class: "btn btn-cancel" - -:javascript - window.project_uploads_path = "#{namespace_project_uploads_path @project.namespace, @project}"; diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml deleted file mode 100644 index 633214a4e869f9d091a47b2968298b5bfa046c4c..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/_main_links.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -%span.pull-right - - if (@page && @page.persisted?) - = link_to history_namespace_project_wiki_path(@project.namespace, @project, @page), class: "btn btn-grouped" do - Page History - - if can?(current_user, :write_wiki, @project) - = link_to edit_namespace_project_wiki_path(@project.namespace, @project, @page), class: "btn btn-grouped" do - %i.fa.fa-pencil-square-o - Edit diff --git a/app/views/projects/wikis/_nav.html.haml b/app/views/projects/wikis/_nav.html.haml deleted file mode 100644 index 693c3facb3286c1f8e9805d2e37fcfe578ee6448..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/_nav.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -%ul.nav.nav-tabs - = nav_link(html_options: {class: params[:id] == 'home' ? 'active' : '' }) do - = link_to 'Home', namespace_project_wiki_path(@project.namespace, @project, :home) - - = nav_link(path: 'wikis#pages') do - = link_to 'Pages', pages_namespace_project_wikis_path(@project.namespace, @project) - - = nav_link(path: 'wikis#git_access') do - = link_to git_access_namespace_project_wikis_path(@project.namespace, @project) do - %i.fa.fa-download - Git Access - - - if can?(current_user, :write_wiki, @project) - .pull-right - = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do - %i.fa.fa-plus - New Page - -= render 'projects/wikis/new' diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml deleted file mode 100644 index 6834969de8b44e3a77b57b5f05fc6758d44e23d3..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/_new.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -%div#modal-new-wiki.modal.hide - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h3.page-title New Wiki Page - .modal-body - = label_tag :new_wiki_path do - %span Page slug - = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => namespace_project_wikis_path(@project.namespace, @project) - %p.hint - Please don't use spaces. - .modal-footer - = link_to 'Build', '#', class: 'build-new-wiki btn btn-create' diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml deleted file mode 100644 index 566850cb78d3487b10593cc71ae2aa8e41c3d203..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/edit.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -= render 'nav' -.pull-right - = render 'main_links' -%h3.page-title - Editing - - %span.light #{@page.title} -%hr -= render 'form' - -.pull-right - - if @page.persisted? && can?(current_user, :admin_wiki, @project) - = link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-sm btn-remove" do - Delete this page diff --git a/app/views/projects/wikis/empty.html.haml b/app/views/projects/wikis/empty.html.haml deleted file mode 100644 index 48058124f97fc28154ae2f46ea4b6fdb4a258c8e..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/empty.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h3.page-title Empty page -%hr -.error_message - You are not allowed to create wiki pages diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml deleted file mode 100644 index 365edb524f43b97124a5f948001958f09a306809..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/git_access.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -= render 'nav' -.row - .col-sm-6 - %h3.page-title - Git access for - %strong= @project_wiki.path_with_namespace - - .col-sm-6 - = render "shared/clone_panel", project: @project_wiki - -.git-empty - %fieldset - %legend Install Gollum: - %pre.dark - :preserve - gem install gollum - - %legend Clone Your Wiki: - %pre.dark - :preserve - git clone #{ content_tag(:span, default_url_to_repo(@project_wiki), class: 'clone')} - cd #{@project_wiki.path} - - %legend Start Gollum And Edit Locally: - %pre.dark - :preserve - gollum - == Sinatra/1.3.5 has taken the stage on 4567 for development with backup from Thin - >> Thin web server (v1.5.0 codename Knife) - >> Maximum connections set to 1024 - >> Listening on 0.0.0.0:4567, CTRL+C to stop diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml deleted file mode 100644 index 91291f753f772e66b579fa0c97cecfcfb8a69aab..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/history.html.haml +++ /dev/null @@ -1,30 +0,0 @@ -= render 'nav' -%h3.page-title - %span.light History for - = link_to @page.title, namespace_project_wiki_path(@project.namespace, @project, @page) - -%table.table - %thead - %tr - %th Page version - %th Author - %th Commit Message - %th Last updated - %th Format - %tbody - - @page.versions.each_with_index do |version, index| - - commit = version - %tr - %td - = link_to project_wiki_path_with_version(@project, @page, - commit.id, index == 0) do - = truncate_sha(commit.id) - %td - = commit.author.name - %td - = commit.message - %td - #{time_ago_with_tooltip(version.authored_date)} - %td - %strong - = @page.page.wiki.page(@page.page.name, commit.id).try(:format) diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml deleted file mode 100644 index ee233d9086f99d02406169cf9881d7dec7cd40ba..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/pages.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -= render 'nav' -%h3.page-title - All Pages -%ul.bordered-list - - @wiki_pages.each do |wiki_page| - %li - %h4 - = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) - %small (#{wiki_page.format}) - .pull-right - %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} -= paginate @wiki_pages, theme: 'gitlab' diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml deleted file mode 100644 index a6263e93f678e515a11429df7755a25772b0af66..0000000000000000000000000000000000000000 --- a/app/views/projects/wikis/show.html.haml +++ /dev/null @@ -1,20 +0,0 @@ -= render 'nav' -%h3.page-title - = @page.title - = render 'main_links' -- if @page.historical? - .warning_message - This is an old version of this page. - You can view the #{link_to "most recent version", namespace_project_wiki_path(@project.namespace, @project, @page)} or browse the #{link_to "history", history_namespace_project_wiki_path(@project.namespace, @project, @page)}. - -%hr - -.wiki-holder - .wiki - = preserve do - = render_wiki_content(@page) - -%hr - -.wiki-last-edit-by - Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)} diff --git a/app/views/search/_filter.html.haml b/app/views/search/_filter.html.haml deleted file mode 100644 index ffc145497abe08dbd90335d997b3cc7272d7a0d8..0000000000000000000000000000000000000000 --- a/app/views/search/_filter.html.haml +++ /dev/null @@ -1,35 +0,0 @@ -.dropdown.inline - %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} - %i.fa.fa-tags - %span.light Group: - - if @group.present? - %strong= @group.name - - else - Any - %b.caret - %ul.dropdown-menu - %li - = link_to search_filter_path(group_id: nil) do - Any - - current_user.authorized_groups.sort_by(&:name).each do |group| - %li - = link_to search_filter_path(group_id: group.id, project_id: nil) do - = group.name - -.dropdown.inline.prepend-left-10.project-filter - %button.dropdown-toggle.btn.btn-sm{type: 'button', 'data-toggle' => 'dropdown'} - %i.fa.fa-tags - %span.light Project: - - if @project.present? - %strong= @project.name_with_namespace - - else - Any - %b.caret - %ul.dropdown-menu - %li - = link_to search_filter_path(project_id: nil) do - Any - - current_user.authorized_projects.sort_by(&:name_with_namespace).each do |project| - %li - = link_to search_filter_path(project_id: project.id, group_id: nil) do - = project.name_with_namespace diff --git a/app/views/search/_global_filter.html.haml b/app/views/search/_global_filter.html.haml deleted file mode 100644 index 442bd84f9308dbd83d864a2715a197d4f0102eaf..0000000000000000000000000000000000000000 --- a/app/views/search/_global_filter.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -%ul.nav.nav-pills.nav-stacked.search-filter - %li{class: ("active" if @scope == 'projects')} - = link_to search_filter_path(scope: 'projects') do - Projects - .pull-right - = @search_results.projects_count - %li{class: ("active" if @scope == 'issues')} - = link_to search_filter_path(scope: 'issues') do - Issues - .pull-right - = @search_results.issues_count - %li{class: ("active" if @scope == 'merge_requests')} - = link_to search_filter_path(scope: 'merge_requests') do - Merge requests - .pull-right - = @search_results.merge_requests_count diff --git a/app/views/search/_project_filter.html.haml b/app/views/search/_project_filter.html.haml deleted file mode 100644 index ad933502a282d928dd92c93c9f604b1f480936bd..0000000000000000000000000000000000000000 --- a/app/views/search/_project_filter.html.haml +++ /dev/null @@ -1,32 +0,0 @@ -%ul.nav.nav-pills.nav-stacked.search-filter - %li{class: ("active" if @scope == 'blobs')} - = link_to search_filter_path(scope: 'blobs') do - %i.fa.fa-code - Code - .pull-right - = @search_results.blobs_count - %li{class: ("active" if @scope == 'issues')} - = link_to search_filter_path(scope: 'issues') do - %i.fa.fa-exclamation-circle - Issues - .pull-right - = @search_results.issues_count - %li{class: ("active" if @scope == 'merge_requests')} - = link_to search_filter_path(scope: 'merge_requests') do - %i.fa.fa-code-fork - Merge requests - .pull-right - = @search_results.merge_requests_count - %li{class: ("active" if @scope == 'notes')} - = link_to search_filter_path(scope: 'notes') do - %i.fa.fa-comments - Comments - .pull-right - = @search_results.notes_count - %li{class: ("active" if @scope == 'wiki_blobs')} - = link_to search_filter_path(scope: 'wiki_blobs') do - %i.fa.fa-book - Wiki - .pull-right - = @search_results.wiki_blobs_count - diff --git a/app/views/search/_results.html.haml b/app/views/search/_results.html.haml deleted file mode 100644 index 796dd752a4c8db68a17e067080dd7a97c3c2a79a..0000000000000000000000000000000000000000 --- a/app/views/search/_results.html.haml +++ /dev/null @@ -1,28 +0,0 @@ -%h4 - #{@search_results.total_count} results found - - unless @show_snippets - - if @project - for #{link_to @project.name_with_namespace, [@project.namespace.becomes(Namespace), @project]} - - elsif @group - for #{link_to @group.name, @group} - -%hr - -.row - .col-sm-3 - - if @project - = render "project_filter" - - elsif @show_snippets - = render 'snippet_filter' - - else - = render "global_filter" - .col-sm-9 - .search-results - - if @search_results.empty? - = render partial: "search/results/empty", locals: { message: "We couldn't find any matching results" } - - else - = render partial: "search/results/#{@scope.singularize}", collection: @objects - = paginate @objects, theme: 'gitlab' - -:javascript - $(".search-results .term").highlight("#{escape_javascript(params[:search])}"); diff --git a/app/views/search/_snippet_filter.html.haml b/app/views/search/_snippet_filter.html.haml deleted file mode 100644 index 95d23fa9f47c9020bfbe38680c00d18b3cf48c18..0000000000000000000000000000000000000000 --- a/app/views/search/_snippet_filter.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%ul.nav.nav-pills.nav-stacked.search-filter - %li{class: ("active" if @scope == 'snippet_blobs')} - = link_to search_filter_path(scope: 'snippet_blobs', snippets: true, group_id: nil, project_id: nil) do - %i.fa.fa-code - Snippet Contents - .pull-right - = @search_results.snippet_blobs_count - %li{class: ("active" if @scope == 'snippet_titles')} - = link_to search_filter_path(scope: 'snippet_titles', snippets: true, group_id: nil, project_id: nil) do - %i.fa.fa-book - Titles and Filenames - .pull-right - = @search_results.snippet_titles_count diff --git a/app/views/search/results/_blob.html.haml b/app/views/search/results/_blob.html.haml deleted file mode 100644 index 84e9be82c444e2596cc2c95472ed282a9e5dd18f..0000000000000000000000000000000000000000 --- a/app/views/search/results/_blob.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -.blob-result - .file-holder - .file-title - = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(blob.ref, blob.filename), :anchor => "L" + blob.startline.to_s) do - %i.fa.fa-file - %strong - = blob.filename - .file-content.code.term - = render 'shared/file_highlight', blob: blob, first_line_number: blob.startline, user_color_scheme_class: 'white' diff --git a/app/views/search/results/_empty.html.haml b/app/views/search/results/_empty.html.haml deleted file mode 100644 index 01fb8cd9b8ec9daaa675c2040626b416f90a520e..0000000000000000000000000000000000000000 --- a/app/views/search/results/_empty.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -.search_box - .search_glyph - %span.fa.fa-search - %h4 #{message} diff --git a/app/views/search/results/_issue.html.haml b/app/views/search/results/_issue.html.haml deleted file mode 100644 index ce8ddff955690ea4895580cdb23945e75fd8bd7d..0000000000000000000000000000000000000000 --- a/app/views/search/results/_issue.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -.search-result-row - %h4 - = link_to [issue.project.namespace.becomes(Namespace), issue.project, issue] do - %span.term.str-truncated= issue.title - .pull-right ##{issue.iid} - - if issue.description.present? - .description.term - = preserve do - = search_md_sanitize(markdown(issue.description)) - %span.light - #{issue.project.name_with_namespace} - - if issue.closed? - .pull-right - %span.label.label-danger Closed diff --git a/app/views/search/results/_merge_request.html.haml b/app/views/search/results/_merge_request.html.haml deleted file mode 100644 index 2efa616d6644e453a53415d6fcf8fbdac5eb4c33..0000000000000000000000000000000000000000 --- a/app/views/search/results/_merge_request.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -.search-result-row - %h4 - = link_to [merge_request.target_project.namespace.becomes(Namespace), merge_request.target_project, merge_request] do - %span.term.str-truncated= merge_request.title - .pull-right ##{merge_request.iid} - - if merge_request.description.present? - .description.term - = preserve do - = search_md_sanitize(markdown(merge_request.description)) - %span.light - #{merge_request.project.name_with_namespace} - .pull-right - - if merge_request.merged? - %span.label.label-primary Merged - - elsif merge_request.closed? - %span.label.label-danger Closed diff --git a/app/views/search/results/_note.html.haml b/app/views/search/results/_note.html.haml deleted file mode 100644 index 5fcba2b7e93b22938d73635dad5295ceb476329b..0000000000000000000000000000000000000000 --- a/app/views/search/results/_note.html.haml +++ /dev/null @@ -1,26 +0,0 @@ -- project = note.project -.search-result-row - %h5.note-search-caption.str-truncated - %i.fa.fa-comment - = link_to_member(project, note.author, avatar: false) - commented on - - - if note.for_commit? - = link_to project do - = project.name_with_namespace - · - = link_to namespace_project_commit_path(project.namespace, project, note.commit_id, anchor: dom_id(note)) do - Commit #{truncate_sha(note.commit_id)} - - else - = link_to project do - = project.name_with_namespace - · - %span #{note.noteable_type.titleize} ##{note.noteable.iid} - · - = link_to [project.namespace.becomes(Namespace), project, note.noteable, anchor: dom_id(note)] do - = note.noteable.title - - .note-search-result - .term - = preserve do - = search_md_sanitize(markdown(note.note, {no_header_anchors: true})) diff --git a/app/views/search/results/_project.html.haml b/app/views/search/results/_project.html.haml deleted file mode 100644 index 195cf06c8ea73fa1b208d7f7556ddef491985ae8..0000000000000000000000000000000000000000 --- a/app/views/search/results/_project.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -.search-result-row - %h4 - = link_to [project.namespace.becomes(Namespace), project] do - %span.term= project.name_with_namespace - - if project.description.present? - %span.light.term= project.description diff --git a/app/views/search/results/_snippet_blob.html.haml b/app/views/search/results/_snippet_blob.html.haml deleted file mode 100644 index 8af393777f0c32d4dde8597c762967769d1ae366..0000000000000000000000000000000000000000 --- a/app/views/search/results/_snippet_blob.html.haml +++ /dev/null @@ -1,59 +0,0 @@ -.search-result-row - %span - = snippet_blob[:snippet_object].title - by - = link_to user_snippets_path(snippet_blob[:snippet_object].author) do - = image_tag avatar_icon(snippet_blob[:snippet_object].author_email), class: "avatar avatar-inline s16", alt: '' - = snippet_blob[:snippet_object].author_name - %span.light #{time_ago_with_tooltip(snippet_blob[:snippet_object].created_at)} - %h4.snippet-title - - snippet_path = reliable_snippet_path(snippet_blob[:snippet_object]) - = link_to snippet_path do - .file-holder - .file-title - %i.fa.fa-file - %strong= snippet_blob[:snippet_object].file_name - - if gitlab_markdown?(snippet_blob[:snippet_object].file_name) - .file-content.wiki - - snippet_blob[:snippet_chunks].each do |snippet| - - unless snippet[:data].empty? - = preserve do - = markdown(snippet[:data]) - - else - .file-content.code - .nothing-here-block Empty file - - elsif markup?(snippet_blob[:snippet_object].file_name) - .file-content.wiki - - snippet_blob[:snippet_chunks].each do |snippet| - - unless snippet[:data].empty? - = render_markup(snippet_blob[:snippet_object].file_name, snippet[:data]) - - else - .file-content.code - .nothing-here-block Empty file - - else - .file-content.code - %div.highlighted-data{class: user_color_scheme_class} - .line-numbers - - snippet_blob[:snippet_chunks].each do |snippet| - - unless snippet[:data].empty? - - snippet[:data].lines.to_a.size.times do |index| - - offset = defined?(snippet[:start_line]) ? snippet[:start_line] : 1 - - i = index + offset - = link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}" do - %i.fa.fa-link - = i - - unless snippet == snippet_blob[:snippet_chunks].last - %a - = "." - .highlight.term - %pre - %code - - snippet_blob[:snippet_chunks].each do |snippet| - - unless snippet[:data].empty? - = snippet[:data] - - unless snippet == snippet_blob[:snippet_chunks].last - %a - = "..." - - else - .file-content.code - .nothing-here-block Empty file diff --git a/app/views/search/results/_snippet_title.html.haml b/app/views/search/results/_snippet_title.html.haml deleted file mode 100644 index c414acb6a11118080b000133a372f6df57984bc9..0000000000000000000000000000000000000000 --- a/app/views/search/results/_snippet_title.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -.search-result-row - %h4.snippet-title.term - = link_to reliable_snippet_path(snippet_title) do - = truncate(snippet_title.title, length: 60) - - if snippet_title.private? - %span.label.label-gray - %i.fa.fa-lock - private - %span.cgray.monospace.tiny.pull-right.term - = snippet_title.file_name - - %small.pull-right.cgray - - if snippet_title.project_id? - = link_to snippet_title.project.name_with_namespace, namespace_project_path(snippet_title.project.namespace, snippet_title.project) - - .snippet-info - = "##{snippet_title.id}" - %span - by - = link_to user_snippets_path(snippet_title.author) do - = image_tag avatar_icon(snippet_title.author_email), class: "avatar avatar-inline s16", alt: '' - = snippet_title.author_name - %span.light #{time_ago_with_tooltip(snippet_title.created_at)} diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml deleted file mode 100644 index f9c5810e3d057962ec92eb8f913e3b7b2c93b4ed..0000000000000000000000000000000000000000 --- a/app/views/search/results/_wiki_blob.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -.blob-result - .file-holder - .file-title - = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_blob.filename) do - %i.fa.fa-file - %strong - = wiki_blob.filename - .file-content.code.term - = render 'shared/file_highlight', blob: wiki_blob, first_line_number: wiki_blob.startline, user_color_scheme_class: 'white' diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml deleted file mode 100644 index 5b4816e4c40d38129309d3b7abca456065d2b95e..0000000000000000000000000000000000000000 --- a/app/views/search/show.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -= form_tag search_path, method: :get, class: 'form-horizontal' do |f| - .search-holder.clearfix - .form-group - = label_tag :search, class: 'control-label' do - %span Looking for - .col-sm-6 - = search_field_tag :search, params[:search], placeholder: "issue 143", class: "form-control search-text-input", id: "dashboard_search" - .col-sm-4 - = button_tag 'Search', class: "btn btn-create" - .form-group - .col-sm-2 - - unless params[:snippets].eql? 'true' - .col-sm-10 - = render 'filter', f: f - = hidden_field_tag :project_id, params[:project_id] - = hidden_field_tag :group_id, params[:group_id] - = hidden_field_tag :snippets, params[:snippets] - = hidden_field_tag :scope, params[:scope] - - .results.prepend-top-10 - - if params[:search].present? - = render 'search/results' diff --git a/app/views/shared/_choose_group_avatar_button.html.haml b/app/views/shared/_choose_group_avatar_button.html.haml deleted file mode 100644 index 000532b1c9a8f8ae71a271345c35eb28bd36f34b..0000000000000000000000000000000000000000 --- a/app/views/shared/_choose_group_avatar_button.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%a.choose-btn.btn.btn-sm.js-choose-group-avatar-button - %i.fa.fa-paperclip - %span Choose File ... -  -%span.file_name.js-avatar-filename File name... -= f.file_field :avatar, class: 'js-group-avatar-input hidden' -.light The maximum file size allowed is 200KB. diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml deleted file mode 100644 index a1121750ca349e0b25ba94fdf77a228385660789..0000000000000000000000000000000000000000 --- a/app/views/shared/_clone_panel.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -- project = project || @project -.git-clone-holder.input-group - .input-group-btn - %button{ | - class: "btn #{ 'active' if default_clone_protocol == 'ssh' }#{ ' has_tooltip' if current_user && current_user.require_ssh_key? }", | - :"data-clone" => project.ssh_url_to_repo, | - :"data-title" => "Add an SSH key to your profile
    to pull or push via SSH", - :"data-html" => "true", - :"data-container" => "body"} - SSH - %button{ | - class: "btn #{ 'active' if default_clone_protocol == 'http' }#{ ' has_tooltip' if current_user && current_user.require_password? }", | - :"data-clone" => project.http_url_to_repo, | - :"data-title" => "Set a password on your account
    to pull or push via #{gitlab_config.protocol.upcase}", - :"data-html" => "true", - :"data-container" => "body"} - = gitlab_config.protocol.upcase - = text_field_tag :project_clone, default_url_to_repo(project), class: "one_click_select form-control", readonly: true - - if project.kind_of?(Project) - .input-group-addon - .visibility-level-label.has_tooltip{'data-title' => "#{visibility_level_label(project.visibility_level)} project" } - = visibility_level_icon(project.visibility_level) - = visibility_level_label(project.visibility_level).downcase diff --git a/app/views/shared/_commit_message_container.html.haml b/app/views/shared/_commit_message_container.html.haml deleted file mode 100644 index 5071ff640f18c08bbe3d0bf0e565defe32221b38..0000000000000000000000000000000000000000 --- a/app/views/shared/_commit_message_container.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -.form-group.commit_message-group - = label_tag 'commit_message', class: 'control-label' do - Commit message - .col-sm-10 - .commit-message-container - .max-width-marker - = text_area_tag 'commit_message', - (params[:commit_message] || local_assigns[:text]), - class: 'form-control', placeholder: local_assigns[:placeholder], - required: true, rows: (local_assigns[:rows] || 3) - - if local_assigns[:hint] - %p.hint - Try to keep the first line under 52 characters - and the others under 72. diff --git a/app/views/shared/_confirm_modal.html.haml b/app/views/shared/_confirm_modal.html.haml deleted file mode 100644 index 30ba361c860530ffaffdb5df9e274b8c71aafc03..0000000000000000000000000000000000000000 --- a/app/views/shared/_confirm_modal.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -#modal-confirm-danger.modal.hide{tabindex: -1} - .modal-dialog - .modal-content - .modal-header - %a.close{href: "#", "data-dismiss" => "modal"} × - %h4 Confirmation required - - .modal-body - %p.cred.lead.js-confirm-text - - %p - This action can lead to data loss. - To prevent accidental actions we ask you to confirm your intention. - %br - Please type - %code.js-confirm-danger-match #{phrase} - to proceed or close this modal to cancel - - .form-group - = text_field_tag 'confirm_name_input', '', class: 'form-control js-confirm-danger-input' - .form-group - = submit_tag 'Confirm', class: "btn btn-danger js-confirm-danger-submit" diff --git a/app/views/shared/_event_filter.html.haml b/app/views/shared/_event_filter.html.haml deleted file mode 100644 index d07a9e2b92468860f9b77d3345b27dc6fff5e97c..0000000000000000000000000000000000000000 --- a/app/views/shared/_event_filter.html.haml +++ /dev/null @@ -1,19 +0,0 @@ -%ul.nav.nav-pills.event_filter - = event_filter_link EventFilter.push, 'Push events' - = event_filter_link EventFilter.merged, 'Merge events' - = event_filter_link EventFilter.comments, 'Comments' - = event_filter_link EventFilter.team, 'Team' - - - if current_user - - if current_controller?(:dashboard) - %li.pull-right - = link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do - %i.fa.fa-rss - News Feed - - - if current_controller?(:groups) - %li.pull-right - = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do - %i.fa.fa-rss - News Feed -%hr diff --git a/app/views/shared/_file_highlight.html.haml b/app/views/shared/_file_highlight.html.haml deleted file mode 100644 index fba69dd0f3fb2974adb6d3ad2e9e2b9002f785b2..0000000000000000000000000000000000000000 --- a/app/views/shared/_file_highlight.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -.file-content.code{class: user_color_scheme_class} - .line-numbers - - if blob.data.present? - - blob.data.lines.to_a.size.times do |index| - - offset = defined?(first_line_number) ? first_line_number : 1 - - i = index + offset - = link_to "#L#{i}", id: "L#{i}", rel: "#L#{i}" do - %i.fa.fa-link - = i - :preserve - #{highlight(blob.name, blob.data)} diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml deleted file mode 100644 index c0a9923348e72b49d8d1bd6d18f177fd06d2ea5b..0000000000000000000000000000000000000000 --- a/app/views/shared/_group_form.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -- if @group.persisted? - .form-group - = f.label :name, class: 'control-label' do - Group name - .col-sm-10 - = f.text_field :name, placeholder: 'open-source', class: 'form-control' - -.form-group - = f.label :path, class: 'control-label' do - Group path - .col-sm-10 - .input-group - .input-group-addon - = root_url - = f.text_field :path, placeholder: 'open-source', class: 'form-control', - autofocus: local_assigns[:autofocus] || false - - if @group.persisted? - .alert.alert-warning.prepend-top-10 - %ul - %li Changing group path can have unintended side effects. - %li Renaming group path will rename directory for all related projects - %li It will change web url for access group and group projects. - %li It will change the git path to repositories under this group. - -.form-group.group-description-holder - = f.label :description, 'Details', class: 'control-label' - .col-sm-10 - = f.text_area :description, maxlength: 250, - class: 'form-control js-gfm-input', rows: 4 diff --git a/app/views/shared/_group_tips.html.haml b/app/views/shared/_group_tips.html.haml deleted file mode 100644 index e5cf783beb7ae21505440dfc6296c159bd382a74..0000000000000000000000000000000000000000 --- a/app/views/shared/_group_tips.html.haml +++ /dev/null @@ -1,6 +0,0 @@ -%ul - %li A group is a collection of several projects - %li Groups are private by default - %li Members of a group may only view projects they have permission to access - %li Group project URLs are prefixed with the group namespace - %li Existing projects may be moved into a group diff --git a/app/views/shared/_issuable_filter.html.haml b/app/views/shared/_issuable_filter.html.haml deleted file mode 100644 index 83f5a3a8015ef276467f55072924b803f2b888e6..0000000000000000000000000000000000000000 --- a/app/views/shared/_issuable_filter.html.haml +++ /dev/null @@ -1,58 +0,0 @@ -.issues-filters - .issues-state-filters - %ul.nav.nav-tabs - %li{class: ("active" if params[:state] == 'opened')} - = link_to page_filter_path(state: 'opened') do - %i.fa.fa-exclamation-circle - Open - %li{class: ("active" if params[:state] == 'closed')} - = link_to page_filter_path(state: 'closed') do - %i.fa.fa-check-circle - Closed - %li{class: ("active" if params[:state] == 'all')} - = link_to page_filter_path(state: 'all') do - %i.fa.fa-compass - All - - .issues-details-filters - = form_tag page_filter_path(without: [:assignee_id, :author_id, :milestone_id, :label_name]), method: :get, class: 'filter-form' do - - if controller.controller_name == 'issues' - .check-all-holder - = check_box_tag "check_all_issues", nil, false, - class: "check_all_issues left", - disabled: !can?(current_user, :modify_issue, @project) - .issues-other-filters - .filter-item.inline - = users_select_tag(:assignee_id, selected: params[:assignee_id], - placeholder: 'Assignee', class: 'trigger-submit', any_user: true, null_user: true, first_user: true) - - .filter-item.inline - = users_select_tag(:author_id, selected: params[:author_id], - placeholder: 'Author', class: 'trigger-submit', any_user: true, first_user: true) - - .filter-item.inline.milestone-filter - = select_tag('milestone_id', projects_milestones_options, class: "select2 trigger-submit", prompt: 'Milestone') - - - if @project - .filter-item.inline.labels-filter - = select_tag('label_name', project_labels_options(@project), class: "select2 trigger-submit", prompt: 'Label') - - .pull-right - = render 'shared/sort_dropdown' - - - if controller.controller_name == 'issues' - .issues_bulk_update.hide - = form_tag bulk_update_namespace_project_issues_path(@project.namespace, @project), method: :post do - = select_tag('update[state_event]', options_for_select([['Open', 'reopen'], ['Closed', 'close']]), prompt: "Status", class: 'form-control') - = users_select_tag('update[assignee_id]', placeholder: 'Assignee', null_user: true) - = select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone") - = hidden_field_tag 'update[issues_ids]', [] - = hidden_field_tag :state_event, params[:state_event] - = button_tag "Update issues", class: "btn update_selected_issues btn-save" - -:coffeescript - new UsersSelect() - - $('form.filter-form').on 'submit', (event) -> - event.preventDefault() - Turbolinks.visit @.action + '&' + $(@).serialize() diff --git a/app/views/shared/_issuable_search_form.html.haml b/app/views/shared/_issuable_search_form.html.haml deleted file mode 100644 index 639d203dcd69007e543e4d433301685a1796dd0c..0000000000000000000000000000000000000000 --- a/app/views/shared/_issuable_search_form.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -= form_tag(path, method: :get, id: "issue_search_form", class: 'pull-left issue-search-form') do - .append-right-10.hidden-xs.hidden-sm - = search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' } - = hidden_field_tag :state, params['state'] - = hidden_field_tag :scope, params['scope'] - = hidden_field_tag :assignee_id, params['assignee_id'] - = hidden_field_tag :author_id, params['author_id'] - = hidden_field_tag :milestone_id, params['milestone_id'] - = hidden_field_tag :label_id, params['label_id'] diff --git a/app/views/shared/_issues.html.haml b/app/views/shared/_issues.html.haml deleted file mode 100644 index 0dbb6a04393720ada519a3b81d158f1a6e7f6b27..0000000000000000000000000000000000000000 --- a/app/views/shared/_issues.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -- if @issues.any? - - @issues.group_by(&:project).each do |group| - .panel.panel-default.panel-small - - project = group[0] - .panel-heading - = link_to_project project - = link_to 'show all', namespace_project_issues_path(project.namespace, project), class: 'pull-right' - - %ul.well-list.issues-list - - group[1].each do |issue| - = render 'projects/issues/issue', issue: issue - = paginate @issues, theme: "gitlab" -- else - .nothing-here-block No issues to show - diff --git a/app/views/shared/_merge_requests.html.haml b/app/views/shared/_merge_requests.html.haml deleted file mode 100644 index c02c5af008a35deffb3599f5c40ac886827e6744..0000000000000000000000000000000000000000 --- a/app/views/shared/_merge_requests.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -- if @merge_requests.any? - - @merge_requests.group_by(&:target_project).each do |group| - .panel.panel-default.panel-small - - project = group[0] - .panel-heading - = link_to_project project - = link_to 'show all', namespace_project_merge_requests_path(project.namespace, project), class: 'pull-right' - %ul.well-list.mr-list - - group[1].each do |merge_request| - = render 'projects/merge_requests/merge_request', merge_request: merge_request - = paginate @merge_requests, theme: "gitlab" - -- else - .nothing-here-block No merge requests to show diff --git a/app/views/shared/_milestones_filter.html.haml b/app/views/shared/_milestones_filter.html.haml deleted file mode 100644 index f685ae7726c62090cb6d495e18b24ba44edee478..0000000000000000000000000000000000000000 --- a/app/views/shared/_milestones_filter.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -.milestones-filters.append-bottom-10 - %ul.nav.nav-tabs - %li{class: ("active" if params[:state].blank? || params[:state] == 'opened')} - = link_to milestones_filter_path(state: 'opened') do - %i.fa.fa-exclamation-circle - Open - %li{class: ("active" if params[:state] == 'closed')} - = link_to milestones_filter_path(state: 'closed') do - %i.fa.fa-check-circle - Closed - %li{class: ("active" if params[:state] == 'all')} - = link_to milestones_filter_path(state: 'all') do - %i.fa.fa-compass - All diff --git a/app/views/shared/_no_password.html.haml b/app/views/shared/_no_password.html.haml deleted file mode 100644 index a43bf33751a9365520535d0e569e4842528541d6..0000000000000000000000000000000000000000 --- a/app/views/shared/_no_password.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -- if cookies[:hide_no_password_message].blank? && !current_user.hide_no_password && current_user.require_password? - .no-password-message.alert.alert-warning.hidden-xs - You won't be able to pull or push project code via #{gitlab_config.protocol.upcase} until you #{link_to 'set a password', edit_profile_password_path} on your account - - .pull-right - = link_to "Don't show again", profile_path(user: {hide_no_password: true}), method: :put - | - = link_to 'Remind later', '#', class: 'hide-no-password-message' diff --git a/app/views/shared/_no_ssh.html.haml b/app/views/shared/_no_ssh.html.haml deleted file mode 100644 index 089179e677aee39c0b6d91b7859d8e4a9afb149b..0000000000000000000000000000000000000000 --- a/app/views/shared/_no_ssh.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -- if cookies[:hide_no_ssh_message].blank? && !current_user.hide_no_ssh_key && current_user.require_ssh_key? - .no-ssh-key-message.alert.alert-warning.hidden-xs - You won't be able to pull or push project code via SSH until you #{link_to 'add an SSH key', new_profile_key_path, class: 'alert-link'} to your profile - - .pull-right - = link_to "Don't show again", profile_path(user: {hide_no_ssh_key: true}), method: :put, class: 'alert-link' - | - = link_to 'Remind later', '#', class: 'hide-no-ssh-message alert-link' diff --git a/app/views/shared/_outdated_browser.html.haml b/app/views/shared/_outdated_browser.html.haml deleted file mode 100644 index 0eba1fe075f35762dbe37f0bae29c77dbfe02db7..0000000000000000000000000000000000000000 --- a/app/views/shared/_outdated_browser.html.haml +++ /dev/null @@ -1,8 +0,0 @@ -- if outdated_browser? - - link = "https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/requirements.md#supported-web-browsers" - .browser-alert - GitLab may not work properly because you are using an outdated web browser. - %br - Please install a - = link_to 'supported web browser', link - for a better experience. diff --git a/app/views/shared/_project.html.haml b/app/views/shared/_project.html.haml deleted file mode 100644 index 722a7f7ce0f467da4a7f88cbfc7ffbbdf5c634f4..0000000000000000000000000000000000000000 --- a/app/views/shared/_project.html.haml +++ /dev/null @@ -1,21 +0,0 @@ -= cache [project.namespace, project, controller.controller_name, controller.action_name] do - = link_to project_path(project), class: dom_class(project) do - - if avatar - .dash-project-avatar - = project_icon(project, alt: '', class: 'avatar project-avatar s40') - .dash-project-access-icon - = visibility_level_icon(project.visibility_level) - %span.str-truncated - %span.namespace-name - - if project.namespace - = project.namespace.human_name - \/ - %span.project-name.filter-title - = project.name - - if stars - %span.pull-right.light - %i.fa.fa-star - = project.star_count - - else - %span.arrow - %i.fa.fa-angle-right diff --git a/app/views/shared/_projects_list.html.haml b/app/views/shared/_projects_list.html.haml deleted file mode 100644 index 4c58092af44ca17c60a75dd231dc87e5556bd179..0000000000000000000000000000000000000000 --- a/app/views/shared/_projects_list.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -- projects_limit = 20 unless local_assigns[:projects_limit] -- avatar = true unless local_assigns[:avatar] == false -- stars = false unless local_assigns[:stars] == true -%ul.well-list.projects-list - - projects.each_with_index do |project, i| - %li{class: (i >= projects_limit) ? 'project-row hide' : 'project-row'} - = render "shared/project", project: project, avatar: avatar, stars: stars - - if projects.blank? - %li - .nothing-here-block There are no projects here. - - if projects.count > projects_limit - %li.bottom - %span.light - #{projects_limit} of #{pluralize(projects.count, 'project')} displayed. - %span - = link_to '#', class: 'js-expand' do - Show all diff --git a/app/views/shared/_promo.html.haml b/app/views/shared/_promo.html.haml deleted file mode 100644 index 3596aabe309d14fc23ea7015fd834436e0d5443c..0000000000000000000000000000000000000000 --- a/app/views/shared/_promo.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -.gitlab-promo - = link_to 'Homepage', promo_url - = link_to "Blog", promo_url + '/blog/' - = link_to "@gitlab", "https://twitter.com/gitlab" - = link_to "Requests", "http://feedback.gitlab.com/" diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml deleted file mode 100644 index eb2e1919e190541aae8b412ccab832b25dbfe79e..0000000000000000000000000000000000000000 --- a/app/views/shared/_ref_switcher.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -= form_tag switch_namespace_project_refs_path(@project.namespace, @project), method: :get, class: "project-refs-form" do - = select_tag "ref", grouped_options_refs, class: "project-refs-select select2 select2-sm" - = hidden_field_tag :destination, destination - - if defined?(path) - = hidden_field_tag :path, path - - @options && @options.each do |key, value| - = hidden_field_tag key, value, id: nil diff --git a/app/views/shared/_sort_dropdown.html.haml b/app/views/shared/_sort_dropdown.html.haml deleted file mode 100644 index af3d35de325d7465360f5764f600d5e2aa7b307c..0000000000000000000000000000000000000000 --- a/app/views/shared/_sort_dropdown.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -.dropdown.inline.prepend-left-10 - %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'} - %span.light sort: - - if @sort.present? - = sort_options_hash[@sort] - - else - = sort_title_recently_created - %b.caret - %ul.dropdown-menu.dropdown-menu-align-right - %li - = link_to page_filter_path(sort: sort_value_recently_created) do - = sort_title_recently_created - = link_to page_filter_path(sort: sort_value_oldest_created) do - = sort_title_oldest_created - = link_to page_filter_path(sort: sort_value_recently_updated) do - = sort_title_recently_updated - = link_to page_filter_path(sort: sort_value_oldest_updated) do - = sort_title_oldest_updated - = link_to page_filter_path(sort: sort_value_milestone_soon) do - = sort_title_milestone_soon - = link_to page_filter_path(sort: sort_value_milestone_later) do - = sort_title_milestone_later diff --git a/app/views/shared/snippets/_blob.html.haml b/app/views/shared/snippets/_blob.html.haml deleted file mode 100644 index 30458793fd13e04ec7538cb3ded4ef91cc92dde0..0000000000000000000000000000000000000000 --- a/app/views/shared/snippets/_blob.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -- unless @snippet.content.empty? - - if gitlab_markdown?(@snippet.file_name) - .file-content.wiki - = preserve do - = markdown(@snippet.data) - - elsif markup?(@snippet.file_name) - .file-content.wiki - = render_markup(@snippet.file_name, @snippet.data) - - else - .file-content.code - = render 'shared/file_highlight', blob: @snippet -- else - .file-content.code - .nothing-here-block Empty file diff --git a/app/views/shared/snippets/_form.html.haml b/app/views/shared/snippets/_form.html.haml deleted file mode 100644 index 4e0663ea2080b087a3226124394d2fddf324925a..0000000000000000000000000000000000000000 --- a/app/views/shared/snippets/_form.html.haml +++ /dev/null @@ -1,41 +0,0 @@ -.snippet-form-holder - = form_for @snippet, url: url, html: { class: "form-horizontal snippet-form" } do |f| - - if @snippet.errors.any? - .alert.alert-danger - %ul - - @snippet.errors.full_messages.each do |msg| - %li= msg - - .form-group - = f.label :title, class: 'control-label' - .col-sm-10= f.text_field :title, placeholder: "Example Snippet", class: 'form-control', required: true - - = render "shared/snippets/visibility_level", f: f, visibility_level: gitlab_config.default_projects_features.visibility_level, can_change_visibility_level: true - - .form-group - .file-editor - = f.label :file_name, "File", class: 'control-label' - .col-sm-10 - .file-holder.snippet - .file-title - = f.text_field :file_name, placeholder: "example.rb", class: 'form-control snippet-file-name', required: true - .file-content.code - %pre#editor= @snippet.content - = f.hidden_field :content, class: 'snippet-file-content' - - .form-actions - - if @snippet.new_record? - = f.submit 'Create snippet', class: "btn-create btn" - - else - = f.submit 'Save', class: "btn-save btn" - - - if @snippet.respond_to?(:project) - = link_to "Cancel", namespace_project_snippets_path(@project.namespace, @project), class: "btn btn-cancel" - - else - = link_to "Cancel", snippets_path(@project), class: "btn btn-cancel" - -:javascript - var editor = ace.edit("editor"); - $(".snippet-form-holder form").submit(function(){ - $(".snippet-file-content").val(editor.getValue()); - }); diff --git a/app/views/shared/snippets/_visibility_level.html.haml b/app/views/shared/snippets/_visibility_level.html.haml deleted file mode 100644 index 9acff18e450f2302e69440df80273a5b73c18ad6..0000000000000000000000000000000000000000 --- a/app/views/shared/snippets/_visibility_level.html.haml +++ /dev/null @@ -1,27 +0,0 @@ -.form-group.project-visibility-level-holder - = f.label :visibility_level, class: 'control-label' do - Visibility Level - = link_to "(?)", help_page_path("public_access", "public_access") - .col-sm-10 - - if can_change_visibility_level - - Gitlab::VisibilityLevel.values.each do |level| - .radio - - restricted = restricted_visibility_levels.include?(level) - = f.radio_button :visibility_level, level, disabled: restricted - = label "#{dom_class(@snippet)}_visibility_level", level do - = visibility_level_icon(level) - .option-title - = visibility_level_label(level) - .option-descr - = snippet_visibility_level_description(level) - - unless restricted_visibility_levels.empty? - .col-sm-10 - %span.info - Some visibility level settings have been restricted by the administrator. - - else - .col-sm-10 - %span.info - = visibility_level_icon(visibility_level) - %strong - = visibility_level_label(visibility_level) - .light= visibility_level_description(visibility_level) diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml deleted file mode 100644 index 5bb28664349416608c23b1c75db98a4ee406f63e..0000000000000000000000000000000000000000 --- a/app/views/snippets/_snippet.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -%li - %h4.snippet-title - = link_to reliable_snippet_path(snippet) do - = truncate(snippet.title, length: 60) - - if snippet.private? - %span.label.label-gray - %i.fa.fa-lock - private - %span.cgray.monospace.tiny.pull-right - = snippet.file_name - - %small.pull-right.cgray - - if snippet.project_id? - = link_to snippet.project.name_with_namespace, namespace_project_path(snippet.project.namespace, snippet.project) - - .snippet-info - = "##{snippet.id}" - %span - by - = link_to user_snippets_path(snippet.author) do - = image_tag avatar_icon(snippet.author_email), class: "avatar avatar-inline s16", alt: '' - = snippet.author_name - %span.light #{time_ago_with_tooltip(snippet.created_at)} diff --git a/app/views/snippets/_snippets.html.haml b/app/views/snippets/_snippets.html.haml deleted file mode 100644 index 40df42b6cf5805d73d67165769621f8528105eec..0000000000000000000000000000000000000000 --- a/app/views/snippets/_snippets.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%ul.bordered-list - = render partial: 'snippet', collection: @snippets - - if @snippets.empty? - %li - .nothing-here-block Nothing here. - -= paginate @snippets, theme: 'gitlab' diff --git a/app/views/snippets/current_user_index.html.haml b/app/views/snippets/current_user_index.html.haml deleted file mode 100644 index 0df5ade500db382bb0e31ec111f6ff37204cc6e5..0000000000000000000000000000000000000000 --- a/app/views/snippets/current_user_index.html.haml +++ /dev/null @@ -1,39 +0,0 @@ -%h3.page-title - Your Snippets - .pull-right - = link_to new_snippet_path, class: "btn btn-new btn-grouped", title: "New Snippet" do - Add new snippet - = link_to snippets_path, class: "btn btn-grouped" do - Discover snippets - -%p.light - Share code pastes with others out of git repository -%hr - -.row - .col-md-3 - %ul.nav.nav-pills.nav-stacked - = nav_tab :scope, nil do - = link_to user_snippets_path(@user) do - All - %span.pull-right - = @user.snippets.count - = nav_tab :scope, 'are_private' do - = link_to user_snippets_path(@user, scope: 'are_private') do - Private - %span.pull-right - = @user.snippets.are_private.count - = nav_tab :scope, 'are_internal' do - = link_to user_snippets_path(@user, scope: 'are_internal') do - Internal - %span.pull-right - = @user.snippets.are_internal.count - = nav_tab :scope, 'are_public' do - = link_to user_snippets_path(@user, scope: 'are_public') do - Public - %span.pull-right - = @user.snippets.are_public.count - - .col-md-9.my-snippets - = render 'snippets' - diff --git a/app/views/snippets/edit.html.haml b/app/views/snippets/edit.html.haml deleted file mode 100644 index 7042d07d5e8bbacf6ba445639e92ecf83a722480..0000000000000000000000000000000000000000 --- a/app/views/snippets/edit.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h3.page-title - Edit snippet -%hr -= render "shared/snippets/form", url: snippet_path(@snippet) diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml deleted file mode 100644 index 5cd8ae26cf9c518bb647ab9876f96d8b815cade1..0000000000000000000000000000000000000000 --- a/app/views/snippets/index.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -%h3.page-title - Public snippets - - .pull-right - - - if current_user - = link_to new_snippet_path, class: "btn btn-new btn-grouped", title: "New Snippet" do - Add new snippet - = link_to user_snippets_path(current_user), class: "btn btn-grouped" do - Your snippets - -%p.light - Public snippets created by you and other users are listed here - -%hr -= render 'snippets' - diff --git a/app/views/snippets/new.html.haml b/app/views/snippets/new.html.haml deleted file mode 100644 index 694d70583173a69cc826c54d853bf2b51f1a9d8a..0000000000000000000000000000000000000000 --- a/app/views/snippets/new.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -%h3.page-title - New snippet -%hr -= render "shared/snippets/form", url: snippets_path(@snippet) diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml deleted file mode 100644 index 5204fb9a90702aca1d752f00e5567ca60c94a7f9..0000000000000000000000000000000000000000 --- a/app/views/snippets/show.html.haml +++ /dev/null @@ -1,43 +0,0 @@ -%h3.page-title - = @snippet.title - - - if @snippet.private? - %span.label.label-success - %i.fa.fa-lock - private - - .pull-right - = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do - Add new snippet -%hr - -.append-bottom-20 - .pull-right - = "##{@snippet.id}" - %span.light - by - = link_to user_snippets_path(@snippet.author) do - = image_tag avatar_icon(@snippet.author_email), class: "avatar avatar-inline s16", alt: '' - = @snippet.author_name - - .back-link - - if @snippet.author == current_user - = link_to user_snippets_path(current_user) do - ← your snippets - - else - = link_to snippets_path do - ← discover snippets - -.file-holder - .file-title - %i.fa.fa-file - %strong - = @snippet.file_name - .file-actions - .btn-group - - if can?(current_user, :modify_personal_snippet, @snippet) - = link_to "edit", edit_snippet_path(@snippet), class: "btn btn-sm", title: 'Edit Snippet' - = link_to "raw", raw_snippet_path(@snippet), class: "btn btn-sm", target: "_blank" - - if can?(current_user, :admin_personal_snippet, @snippet) - = link_to "remove", snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-sm btn-remove", title: 'Delete Snippet' - = render 'shared/snippets/blob' diff --git a/app/views/snippets/user_index.html.haml b/app/views/snippets/user_index.html.haml deleted file mode 100644 index df524cd18b0cb46b01612a3c6976605dccc336ba..0000000000000000000000000000000000000000 --- a/app/views/snippets/user_index.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -%h3.page-title - = image_tag avatar_icon(@user.email), class: "avatar s24" - = @user.name - %span - \/ - Snippets - - if current_user - = link_to new_snippet_path, class: "btn btn-sm add_new pull-right", title: "New Snippet" do - Add new snippet - -%hr - -= render 'snippets' diff --git a/app/views/users/_groups.html.haml b/app/views/users/_groups.html.haml deleted file mode 100644 index f360fbb3d5d94159871f64e52cf0b9dae86a4886..0000000000000000000000000000000000000000 --- a/app/views/users/_groups.html.haml +++ /dev/null @@ -1,4 +0,0 @@ -.clearfix - - groups.each do |group| - = link_to group, class: 'profile-groups-avatars inline', title: group.name do - = image_tag group_icon(group), class: 'avatar group-avatar s40' diff --git a/app/views/users/_profile.html.haml b/app/views/users/_profile.html.haml deleted file mode 100644 index 90d9980c85ca44e9a127a9378f6b7279d5e22694..0000000000000000000000000000000000000000 --- a/app/views/users/_profile.html.haml +++ /dev/null @@ -1,31 +0,0 @@ -.panel.panel-default - .panel-heading - Profile - %ul.well-list - %li - %span.light Member since - %strong= user.created_at.stamp("Aug 21, 2011") - - unless user.public_email.blank? - %li - %span.light E-mail: - %strong= link_to user.public_email, "mailto:#{user.public_email}" - - unless user.skype.blank? - %li - %span.light Skype: - %strong= link_to user.skype, "skype:#{user.skype}" - - unless user.linkedin.blank? - %li - %span.light LinkedIn: - %strong= link_to user.linkedin, "http://www.linkedin.com/in/#{user.linkedin}" - - unless user.twitter.blank? - %li - %span.light Twitter: - %strong= link_to user.twitter, "http://www.twitter.com/#{user.twitter}" - - unless user.website_url.blank? - %li - %span.light Website: - %strong= link_to user.short_website_url, user.full_website_url - - unless user.location.blank? - %li - %span.light Location: - %strong= user.location diff --git a/app/views/users/_projects.html.haml b/app/views/users/_projects.html.haml deleted file mode 100644 index 297fa53739407271eb9303bb51c9ce827ce59d45..0000000000000000000000000000000000000000 --- a/app/views/users/_projects.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -- if local_assigns.has_key?(:contributed_projects) && contributed_projects.present? - .panel.panel-default.contributed-projects - .panel-heading Projects contributed to - = render 'shared/projects_list', - projects: contributed_projects.sort_by(&:star_count).reverse, - projects_limit: 5, stars: true, avatar: false - -- if local_assigns.has_key?(:projects) && projects.present? - .panel.panel-default - .panel-heading Personal projects - = render 'shared/projects_list', - projects: projects.sort_by(&:star_count).reverse, - projects_limit: 10, stars: true, avatar: false diff --git a/app/views/users/calendar.html.haml b/app/views/users/calendar.html.haml deleted file mode 100644 index 922b0c6cebf1cb1425ec056195bc15025cf434d2..0000000000000000000000000000000000000000 --- a/app/views/users/calendar.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -%h4 - Contributions calendar - .pull-right - %small Issues, merge requests and push events -#cal-heatmap.calendar - :javascript - new Calendar( - #{@timestamps.to_json}, - #{@starting_year}, - #{@starting_month}, - '#{user_calendar_activities_path}' - ); diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml deleted file mode 100644 index 027a93a75fcd9ba317e1dc0b44c9e1b3035b1321..0000000000000000000000000000000000000000 --- a/app/views/users/calendar_activities.html.haml +++ /dev/null @@ -1,23 +0,0 @@ -%h4.prepend-top-20 - %span.light Contributions for - %strong #{@calendar_date.to_s(:short)} - -%ul.bordered-list - - @events.sort_by(&:created_at).each do |event| - %li - %span.light - %i.fa.fa-clock-o - = event.created_at.to_s(:time) - - if event.push? - #{event.action_name} #{event.ref_type} #{event.ref_name} - - else - = event_action_name(event) - - if event.target - %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target] - - at - %strong - - if event.project - = link_to_project event.project - - else - = event.project_name diff --git a/app/views/users/show.atom.builder b/app/views/users/show.atom.builder deleted file mode 100644 index 8fe30b23635fd58e414485a3a3510c36b135effe..0000000000000000000000000000000000000000 --- a/app/views/users/show.atom.builder +++ /dev/null @@ -1,12 +0,0 @@ -xml.instruct! -xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do - xml.title "Activity feed for #{@user.name}" - xml.link href: user_url(@user, :atom), rel: "self", type: "application/atom+xml" - xml.link href: user_url(@user), rel: "alternate", type: "text/html" - xml.id projects_url - xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? - - @events.each do |event| - event_to_atom(xml, event) - end -end diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml deleted file mode 100644 index 9dd8cb0738c55bb681aca50603a100e6369d82e2..0000000000000000000000000000000000000000 --- a/app/views/users/show.html.haml +++ /dev/null @@ -1,50 +0,0 @@ -.row - = link_to '#aside', class: 'show-aside' do - %i.fa.fa-angle-left - %section.col-md-8 - .header-with-avatar - = image_tag avatar_icon(@user.email, 90), class: "avatar avatar-tile s90", alt: '' - %h3 - = @user.name - - if @user == current_user - .pull-right - = link_to profile_path, class: 'btn btn-sm' do - %i.fa.fa-pencil-square-o - Edit Profile settings - .username - @#{@user.username} - .description - - if @user.bio.present? - = @user.bio - - .clearfix - - - if @groups.any? - .prepend-top-20 - %h4 Groups - = render 'groups', groups: @groups - %hr - - .hidden-xs - .user-calendar - %h4.center.light - %i.fa.fa-spinner.fa-spin - .user-calendar-activities - %hr - %h4 - User Activity - - - if current_user - %span.rss-icon.pull-right - = link_to user_path(@user, :atom, { private_token: current_user.private_token }) do - %strong - %i.fa.fa-rss - - .content_list - = spinner - %aside.col-md-4 - = render 'profile', user: @user - = render 'projects', projects: @projects, contributed_projects: @contributed_projects - -:coffeescript - $(".user-calendar").load("#{user_calendar_path}") diff --git a/app/views/votes/_votes_block.html.haml b/app/views/votes/_votes_block.html.haml deleted file mode 100644 index 36ea67420641ee8af1d63bf450107dc4e56f00ba..0000000000000000000000000000000000000000 --- a/app/views/votes/_votes_block.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -.votes.votes-block - .btn-group - - unless votable.upvotes.zero? - .btn.btn-sm.disabled.cgreen - %i.fa.fa-thumbs-up - = votable.upvotes - - unless votable.downvotes.zero? - .btn.btn-sm.disabled.cred - %i.fa.fa-thumbs-down - = votable.downvotes diff --git a/app/views/votes/_votes_inline.html.haml b/app/views/votes/_votes_inline.html.haml deleted file mode 100644 index 2cb3ae04e1a83b670b824993ee5a59e1dcf29684..0000000000000000000000000000000000000000 --- a/app/views/votes/_votes_inline.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -.votes.votes-inline - - unless votable.upvotes.zero? - %span.upvotes.cgreen - + #{votable.upvotes} - - unless votable.downvotes.zero? - \/ - - unless votable.downvotes.zero? - %span.downvotes.cred - \- #{votable.downvotes} diff --git a/app/workers/auto_merge_worker.rb b/app/workers/auto_merge_worker.rb deleted file mode 100644 index a6dd73eee5f81c8cff509d63b2294c0b05ae26a0..0000000000000000000000000000000000000000 --- a/app/workers/auto_merge_worker.rb +++ /dev/null @@ -1,13 +0,0 @@ -class AutoMergeWorker - include Sidekiq::Worker - - sidekiq_options queue: :default - - def perform(merge_request_id, current_user_id, params) - params = params.with_indifferent_access - current_user = User.find(current_user_id) - merge_request = MergeRequest.find(merge_request_id) - merge_request.should_remove_source_branch = params[:should_remove_source_branch] - merge_request.automerge!(current_user, params[:commit_message]) - end -end diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb deleted file mode 100644 index 1d21addece6df43d48a79a6c0e5d478c47e06ef3..0000000000000000000000000000000000000000 --- a/app/workers/emails_on_push_worker.rb +++ /dev/null @@ -1,61 +0,0 @@ -class EmailsOnPushWorker - include Sidekiq::Worker - - def perform(project_id, recipients, push_data, options = {}) - options.symbolize_keys! - options.reverse_merge!( - send_from_committer_email: false, - disable_diffs: false - ) - send_from_committer_email = options[:send_from_committer_email] - disable_diffs = options[:disable_diffs] - - project = Project.find(project_id) - before_sha = push_data["before"] - after_sha = push_data["after"] - ref = push_data["ref"] - author_id = push_data["user_id"] - - action = - if Gitlab::Git.blank_ref?(before_sha) - :create - elsif Gitlab::Git.blank_ref?(after_sha) - :delete - else - :push - end - - compare = nil - reverse_compare = false - if action == :push - compare = Gitlab::Git::Compare.new(project.repository.raw_repository, before_sha, after_sha) - - return false if compare.same - - if compare.commits.empty? - compare = Gitlab::Git::Compare.new(project.repository.raw_repository, after_sha, before_sha) - - reverse_compare = true - - return false if compare.commits.empty? - end - end - - recipients.split(" ").each do |recipient| - Notify.repository_push_email( - project_id, - recipient, - author_id: author_id, - ref: ref, - action: action, - compare: compare, - reverse_compare: reverse_compare, - send_from_committer_email: send_from_committer_email, - disable_diffs: disable_diffs - ).deliver - end - ensure - compare = nil - GC.start - end -end diff --git a/app/workers/fork_registration_worker.rb b/app/workers/fork_registration_worker.rb deleted file mode 100644 index fffa8b3a65913c12759c76c604ee8d10967f7c1b..0000000000000000000000000000000000000000 --- a/app/workers/fork_registration_worker.rb +++ /dev/null @@ -1,12 +0,0 @@ -class ForkRegistrationWorker - include Sidekiq::Worker - - sidekiq_options queue: :default - - def perform(from_project_id, to_project_id, private_token) - from_project = Project.find(from_project_id) - to_project = Project.find(to_project_id) - - from_project.gitlab_ci_service.fork_registration(to_project, private_token) - end -end diff --git a/app/workers/gitlab_shell_worker.rb b/app/workers/gitlab_shell_worker.rb deleted file mode 100644 index cfeda88bbc5c6ceaef5d19215cf32b1dc77aa131..0000000000000000000000000000000000000000 --- a/app/workers/gitlab_shell_worker.rb +++ /dev/null @@ -1,10 +0,0 @@ -class GitlabShellWorker - include Sidekiq::Worker - include Gitlab::ShellAdapter - - sidekiq_options queue: :gitlab_shell - - def perform(action, *arg) - gitlab_shell.send(action, *arg) - end -end diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb deleted file mode 100644 index 8b50f423984f8f452b0c8ada50d6250143a6d7fb..0000000000000000000000000000000000000000 --- a/app/workers/irker_worker.rb +++ /dev/null @@ -1,169 +0,0 @@ -require 'json' -require 'socket' - -class IrkerWorker - include Sidekiq::Worker - - def perform(project_id, chans, colors, push_data, settings) - project = Project.find(project_id) - - # Get config parameters - return false unless init_perform settings, chans, colors - - repo_name = push_data['repository']['name'] - committer = push_data['user_name'] - branch = push_data['ref'].gsub(%r'refs/[^/]*/', '') - - if @colors - repo_name = "\x0304#{repo_name}\x0f" - branch = "\x0305#{branch}\x0f" - end - - # Firsts messages are for branch creation/deletion - send_branch_updates push_data, project, repo_name, committer, branch - - # Next messages are for commits - send_commits push_data, project, repo_name, committer, branch - - close_connection - true - end - - private - - def init_perform(set, chans, colors) - @colors = colors - @channels = chans - start_connection set['server_ip'], set['server_port'] - end - - def start_connection(irker_server, irker_port) - begin - @socket = TCPSocket.new irker_server, irker_port - rescue Errno::ECONNREFUSED => e - logger.fatal "Can't connect to Irker daemon: #{e}" - return false - end - true - end - - def sendtoirker(privmsg) - to_send = { to: @channels, privmsg: privmsg } - @socket.puts JSON.dump(to_send) - end - - def close_connection - @socket.close - end - - def send_branch_updates(push_data, project, repo_name, committer, branch) - if Gitlab::Git.blank_ref?(push_data['before']) - send_new_branch project, repo_name, committer, branch - elsif Gitlab::Git.blank_ref?(push_data['after']) - send_del_branch repo_name, committer, branch - end - end - - def send_new_branch(project, repo_name, committer, branch) - repo_path = project.path_with_namespace - newbranch = "#{Gitlab.config.gitlab.url}/#{repo_path}/branches" - newbranch = "\x0302\x1f#{newbranch}\x0f" if @colors - - privmsg = "[#{repo_name}] #{committer} has created a new branch " - privmsg += "#{branch}: #{newbranch}" - sendtoirker privmsg - end - - def send_del_branch(repo_name, committer, branch) - privmsg = "[#{repo_name}] #{committer} has deleted the branch #{branch}" - sendtoirker privmsg - end - - def send_commits(push_data, project, repo_name, committer, branch) - return if push_data['total_commits_count'] == 0 - - # Next message is for number of commit pushed, if any - if Gitlab::Git.blank_ref?(push_data['before']) - # Tweak on push_data["before"] in order to have a nice compare URL - push_data['before'] = before_on_new_branch push_data, project - end - - send_commits_count(push_data, project, repo_name, committer, branch) - - # One message per commit, limited by 3 messages (same limit as the - # github irc hook) - commits = push_data['commits'].first(3) - commits.each do |hook_attrs| - send_one_commit project, hook_attrs, repo_name, branch - end - end - - def before_on_new_branch(push_data, project) - commit = commit_from_id project, push_data['commits'][0]['id'] - parents = commit.parents - # Return old value if there's no new one - return push_data['before'] if parents.empty? - # Or return the first parent-commit - parents[0].id - end - - def send_commits_count(data, project, repo, committer, branch) - url = compare_url data, project.path_with_namespace - commits = colorize_commits data['total_commits_count'] - - new_commits = 'new commit' - new_commits += 's' if data['total_commits_count'] > 1 - - sendtoirker "[#{repo}] #{committer} pushed #{commits} #{new_commits} " \ - "to #{branch}: #{url}" - end - - def compare_url(data, repo_path) - sha1 = Commit::truncate_sha(data['before']) - sha2 = Commit::truncate_sha(data['after']) - compare_url = "#{Gitlab.config.gitlab.url}/#{repo_path}/compare" - compare_url += "/#{sha1}...#{sha2}" - colorize_url compare_url - end - - def send_one_commit(project, hook_attrs, repo_name, branch) - commit = commit_from_id project, hook_attrs['id'] - sha = colorize_sha Commit::truncate_sha(hook_attrs['id']) - author = hook_attrs['author']['name'] - files = colorize_nb_files(files_count commit) - title = commit.title - - sendtoirker "#{repo_name}/#{branch} #{sha} #{author} (#{files}): #{title}" - end - - def commit_from_id(project, id) - commit = Gitlab::Git::Commit.find(project.repository, id) - Commit.new(commit) - end - - def files_count(commit) - files = "#{commit.diffs.count} file" - files += 's' if commit.diffs.count > 1 - files - end - - def colorize_sha(sha) - sha = "\x0314#{sha}\x0f" if @colors - sha - end - - def colorize_nb_files(nb_files) - nb_files = "\x0312#{nb_files}\x0f" if @colors - nb_files - end - - def colorize_url(url) - url = "\x0302\x1f#{url}\x0f" if @colors - url - end - - def colorize_commits(commits) - commits = "\x02#{commits}\x0f" if @colors - commits - end -end diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb deleted file mode 100644 index 33d8cc8861be8ebe23b24d1ff1dc4362316dcacd..0000000000000000000000000000000000000000 --- a/app/workers/post_receive.rb +++ /dev/null @@ -1,62 +0,0 @@ -class PostReceive - include Sidekiq::Worker - include Gitlab::Identifier - - sidekiq_options queue: :post_receive - - def perform(repo_path, identifier, changes) - if repo_path.start_with?(Gitlab.config.gitlab_shell.repos_path.to_s) - repo_path.gsub!(Gitlab.config.gitlab_shell.repos_path.to_s, "") - else - log("Check gitlab.yml config for correct gitlab_shell.repos_path variable. \"#{Gitlab.config.gitlab_shell.repos_path}\" does not match \"#{repo_path}\"") - end - - repo_path.gsub!(/\.git\z/, "") - repo_path.gsub!(/\A\//, "") - - project = Project.find_with_namespace(repo_path) - - if project.nil? - log("Triggered hook for non-existing project with full path \"#{repo_path} \"") - return false - end - - changes = Base64.decode64(changes) unless changes.include?(" ") - changes = utf8_encode_changes(changes) - changes = changes.lines - - changes.each do |change| - oldrev, newrev, ref = change.strip.split(' ') - - @user ||= identify(identifier, project, newrev) - - unless @user - log("Triggered hook for non-existing user \"#{identifier} \"") - return false - end - - if Gitlab::Git.tag_ref?(ref) - GitTagPushService.new.execute(project, @user, oldrev, newrev, ref) - else - GitPushService.new.execute(project, @user, oldrev, newrev, ref) - end - end - end - - def utf8_encode_changes(changes) - changes = changes.dup - - changes.force_encoding("UTF-8") - return changes if changes.valid_encoding? - - # Convert non-UTF-8 branch/tag names to UTF-8 so they can be dumped as JSON. - detection = CharlockHolmes::EncodingDetector.detect(changes) - return changes unless detection && detection[:encoding] - - CharlockHolmes::Converter.convert(changes, detection[:encoding], 'UTF-8') - end - - def log(message) - Gitlab::GitLogger.error("POST-RECEIVE: #{message}") - end -end diff --git a/app/workers/project_service_worker.rb b/app/workers/project_service_worker.rb deleted file mode 100644 index 64d39c4d3f7ef436cb4ee49e2a2d4d9a5a5ee72a..0000000000000000000000000000000000000000 --- a/app/workers/project_service_worker.rb +++ /dev/null @@ -1,10 +0,0 @@ -class ProjectServiceWorker - include Sidekiq::Worker - - sidekiq_options queue: :project_web_hook - - def perform(hook_id, data) - data = data.with_indifferent_access - Service.find(hook_id).execute(data) - end -end diff --git a/app/workers/project_web_hook_worker.rb b/app/workers/project_web_hook_worker.rb deleted file mode 100644 index 73085c046bd6ab50ab3183a7178ab196939f3ad9..0000000000000000000000000000000000000000 --- a/app/workers/project_web_hook_worker.rb +++ /dev/null @@ -1,10 +0,0 @@ -class ProjectWebHookWorker - include Sidekiq::Worker - - sidekiq_options queue: :project_web_hook - - def perform(hook_id, data) - data = data.with_indifferent_access - WebHook.find(hook_id).execute(data) - end -end diff --git a/app/workers/repository_archive_worker.rb b/app/workers/repository_archive_worker.rb deleted file mode 100644 index 021c1139568b8bfc5ca6b259d57bb16bbaab5d7f..0000000000000000000000000000000000000000 --- a/app/workers/repository_archive_worker.rb +++ /dev/null @@ -1,43 +0,0 @@ -class RepositoryArchiveWorker - include Sidekiq::Worker - - sidekiq_options queue: :archive_repo - - attr_accessor :project, :ref, :format - - def perform(project_id, ref, format) - @project = Project.find(project_id) - @ref, @format = ref, format.downcase - - repository = project.repository - - repository.clean_old_archives - - return unless file_path - return if archived? || archiving? - - repository.archive_repo(ref, storage_path, format) - end - - private - - def storage_path - Gitlab.config.gitlab.repository_downloads_path - end - - def file_path - @file_path ||= project.repository.archive_file_path(ref, storage_path, format) - end - - def pid_file_path - @pid_file_path ||= project.repository.archive_pid_file_path(ref, storage_path, format) - end - - def archived? - File.exist?(file_path) - end - - def archiving? - File.exist?(pid_file_path) - end -end diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb deleted file mode 100644 index e6a50afedb12003bb99c3ebb09056097767733c3..0000000000000000000000000000000000000000 --- a/app/workers/repository_import_worker.rb +++ /dev/null @@ -1,34 +0,0 @@ -class RepositoryImportWorker - include Sidekiq::Worker - include Gitlab::ShellAdapter - - sidekiq_options queue: :gitlab_shell - - def perform(project_id) - project = Project.find(project_id) - - import_result = gitlab_shell.send(:import_repository, - project.path_with_namespace, - project.import_url) - return project.import_fail unless import_result - - data_import_result = if project.import_type == 'github' - Gitlab::GithubImport::Importer.new(project).execute - elsif project.import_type == 'gitlab' - Gitlab::GitlabImport::Importer.new(project).execute - elsif project.import_type == 'bitbucket' - Gitlab::BitbucketImport::Importer.new(project).execute - elsif project.import_type == 'google_code' - Gitlab::GoogleCodeImport::Importer.new(project).execute - else - true - end - return project.import_fail unless data_import_result - - project.import_finish - project.save - project.satellite.create unless project.satellite.exists? - project.update_repository_size - Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket' - end -end diff --git a/app/workers/system_hook_worker.rb b/app/workers/system_hook_worker.rb deleted file mode 100644 index 3ebc62b7e7a5a890d01f65b492b14ba6b76d60aa..0000000000000000000000000000000000000000 --- a/app/workers/system_hook_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -class SystemHookWorker - include Sidekiq::Worker - - sidekiq_options queue: :system_hook - - def perform(hook_id, data) - SystemHook.find(hook_id).execute data - end -end diff --git a/bin/background_jobs b/bin/background_jobs deleted file mode 100755 index a041a4b0433b292aa3785d089b5e909a4e1400ea..0000000000000000000000000000000000000000 --- a/bin/background_jobs +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh - -cd $(dirname $0)/.. -app_root=$(pwd) -sidekiq_pidfile="$app_root/tmp/pids/sidekiq.pid" -sidekiq_logfile="$app_root/log/sidekiq.log" -gitlab_user=$(ls -l config.ru | awk '{print $3}') - -warn() -{ - echo "$@" 1>&2 -} - -stop() -{ - bundle exec sidekiqctl stop $sidekiq_pidfile >> $sidekiq_logfile 2>&1 -} - -killall() -{ - pkill -u $gitlab_user -f 'sidekiq [0-9]' -} - -restart() -{ - if [ -f $sidekiq_pidfile ]; then - stop - fi - killall - start_sidekiq -d -L $sidekiq_logfile -} - -start_no_deamonize() -{ - start_sidekiq -} - -start_sidekiq() -{ - bundle exec sidekiq -q post_receive -q mailer -q archive_repo -q system_hook -q project_web_hook -q gitlab_shell -q common -q default -e $RAILS_ENV -P $sidekiq_pidfile $@ >> $sidekiq_logfile 2>&1 -} - -load_ok() -{ - sidekiq_pid=$(cat $sidekiq_pidfile) - if [ -z "$sidekiq_pid" ] ; then - warn "Could not find a PID in $sidekiq_pidfile" - exit 0 - fi - - if (ps -p $sidekiq_pid -o args | grep '\([0-9]\+\) of \1 busy' 1>&2) ; then - warn "Too many busy Sidekiq workers" - exit 1 - fi - - exit 0 -} - -case "$1" in - stop) - stop - ;; - start) - restart - ;; - start_no_deamonize) - start_no_deamonize - ;; - restart) - restart - ;; - killall) - killall - ;; - load_ok) - load_ok - ;; - *) - echo "Usage: RAILS_ENV=your_env $0 {stop|start|start_no_deamonize|restart|killall|load_ok}" -esac diff --git a/bin/bundle b/bin/bundle deleted file mode 100755 index 66e9889e8b4aeea1af13e2396fb70594232a2ae3..0000000000000000000000000000000000000000 --- a/bin/bundle +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env ruby -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) -load Gem.bin_path('bundler', 'bundle') diff --git a/bin/check b/bin/check deleted file mode 100755 index c907a98b5d91d15915256870a73985d58c5cda5d..0000000000000000000000000000000000000000 --- a/bin/check +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production diff --git a/bin/guard b/bin/guard deleted file mode 100755 index 0c1a532bd01d7e797faaba230577d39c57f31208..0000000000000000000000000000000000000000 --- a/bin/guard +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env ruby -# -# This file was generated by Bundler. -# -# The application 'guard' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'pathname' -ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) - -require 'rubygems' -require 'bundler/setup' - -load Gem.bin_path('guard', 'guard') diff --git a/bin/pkgr_before_precompile.sh b/bin/pkgr_before_precompile.sh deleted file mode 100755 index 5a2007f4ab0ba511d3b3d6e9cf987709811387a1..0000000000000000000000000000000000000000 --- a/bin/pkgr_before_precompile.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -set -e - -for file in config/*.yml.example; do - cp ${file} config/$(basename ${file} .example) -done - -# Allow to override the Gitlab URL from an environment variable, as this will avoid having to change the configuration file for simple deployments. -config=$(echo '<% gitlab_url = URI(ENV["GITLAB_URL"] || "http://localhost:80") %>' | cat - config/gitlab.yml) -echo "$config" > config/gitlab.yml -sed -i "s/host: localhost/host: <%= gitlab_url.host %>/" config/gitlab.yml -sed -i "s/port: 80/port: <%= gitlab_url.port %>/" config/gitlab.yml -sed -i "s/https: false/https: <%= gitlab_url.scheme == 'https' %>/" config/gitlab.yml - -# No need for config file. Will be taken care of by REDIS_URL env variable -rm config/resque.yml - -# Set default unicorn.rb file -echo "" > config/unicorn.rb diff --git a/bin/rails b/bin/rails deleted file mode 100755 index 7feb6a30e696bf9b94f204c6abb5c4d75f965046..0000000000000000000000000000000000000000 --- a/bin/rails +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env ruby -begin - load File.expand_path("../spring", __FILE__) -rescue LoadError -end -APP_PATH = File.expand_path('../../config/application', __FILE__) -require_relative '../config/boot' -require 'rails/commands' diff --git a/bin/rake b/bin/rake deleted file mode 100755 index 8017a0271d2130252500c4ef0f5bdf3b39582480..0000000000000000000000000000000000000000 --- a/bin/rake +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env ruby -begin - load File.expand_path("../spring", __FILE__) -rescue LoadError -end -require_relative '../config/boot' -require 'rake' -Rake.application.run diff --git a/bin/rspec b/bin/rspec deleted file mode 100755 index 20060ebd79c0ec217596c425ddc66ea58b4a02d1..0000000000000000000000000000000000000000 --- a/bin/rspec +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env ruby -begin - load File.expand_path("../spring", __FILE__) -rescue LoadError -end -require 'bundler/setup' -load Gem.bin_path('rspec-core', 'rspec') diff --git a/bin/spinach b/bin/spinach deleted file mode 100755 index a080e286cfe025ec2c80934395e9020c1c1f9812..0000000000000000000000000000000000000000 --- a/bin/spinach +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env ruby -begin - load File.expand_path("../spring", __FILE__) -rescue LoadError -end -require 'bundler/setup' -load Gem.bin_path('spinach', 'spinach') diff --git a/bin/spring b/bin/spring deleted file mode 100755 index 253ec37c3451d65eb54c64d59cdeaf41a1c8aafc..0000000000000000000000000000000000000000 --- a/bin/spring +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env ruby - -# This file loads spring without using Bundler, in order to be fast -# It gets overwritten when you run the `spring binstub` command - -unless defined?(Spring) - require "rubygems" - require "bundler" - - if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ spring \((.*?)\)$.*?^$/m) - ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR) - ENV["GEM_HOME"] = "" - Gem.paths = ENV - - gem "spring", match[1] - require "spring/binstub" - end -end diff --git a/bin/upgrade.rb b/bin/upgrade.rb deleted file mode 100644 index a5caecf8526e8b08dbc2ba4880bbc85d46c2635e..0000000000000000000000000000000000000000 --- a/bin/upgrade.rb +++ /dev/null @@ -1,3 +0,0 @@ -require_relative "../lib/gitlab/upgrader" - -Gitlab::Upgrader.new.execute diff --git a/bin/web b/bin/web deleted file mode 100755 index 67f236eb0bb67005d69c99164629dfeb914f9d36..0000000000000000000000000000000000000000 --- a/bin/web +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -cd $(dirname $0)/.. -app_root=$(pwd) - -unicorn_pidfile="$app_root/tmp/pids/unicorn.pid" -unicorn_config="$app_root/config/unicorn.rb" - -get_unicorn_pid() -{ - local pid=$(cat $unicorn_pidfile) - if [ -z "$pid" ] ; then - echo "Could not find a PID in $unicorn_pidfile" - exit 1 - fi - unicorn_pid=$pid -} - -start() -{ - bundle exec unicorn_rails -D -c $unicorn_config -E $RAILS_ENV -} - -stop() -{ - get_unicorn_pid - kill -QUIT $unicorn_pid -} - -reload() -{ - get_unicorn_pid - kill -USR2 $unicorn_pid -} - -case "$1" in - start) - start - ;; - stop) - stop - ;; - reload) - reload - ;; - *) - echo "Usage: RAILS_ENV=your_env $0 {start|stop|reload}" - ;; -esac diff --git a/config.ru b/config.ru deleted file mode 100644 index e90863a5c21baf365868b4ad325c88cd52338949..0000000000000000000000000000000000000000 --- a/config.ru +++ /dev/null @@ -1,16 +0,0 @@ -# This file is used by Rack-based servers to start the application. - -if defined?(Unicorn) - require 'unicorn' - # Unicorn self-process killer - require 'unicorn/worker_killer' - - # Max memory size (RSS) per worker - use Unicorn::WorkerKiller::Oom, (200 * (1 << 20)), (250 * (1 << 20)) -end - -require ::File.expand_path('../config/environment', __FILE__) - -map ENV['RAILS_RELATIVE_URL_ROOT'] || "/" do - run Gitlab::Application -end diff --git a/config/application.rb b/config/application.rb deleted file mode 100644 index fa399533e523cf81a9a77b779d5ecfac2f4697e9..0000000000000000000000000000000000000000 --- a/config/application.rb +++ /dev/null @@ -1,104 +0,0 @@ -require File.expand_path('../boot', __FILE__) - -require 'rails/all' -require 'devise' -I18n.config.enforce_available_locales = false -Bundler.require(:default, Rails.env) - -module Gitlab - class Application < Rails::Application - # Settings in config/environments/* take precedence over those specified here. - # Application configuration should go into files in config/initializers - # -- all .rb files in that directory are automatically loaded. - - # Custom directories with classes and modules you want to be autoloadable. - config.autoload_paths.push(*%W(#{config.root}/lib - #{config.root}/app/models/hooks - #{config.root}/app/models/concerns - #{config.root}/app/models/project_services - #{config.root}/app/models/members)) - - # Only load the plugins named here, in the order given (default is alphabetical). - # :all can be used as a placeholder for all plugins not explicitly named. - # config.plugins = [ :exception_notification, :ssl_requirement, :all ] - - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. - # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - # config.i18n.default_locale = :de - config.i18n.enforce_available_locales = false - - # Configure the default encoding used in templates for Ruby 1.9. - config.encoding = "utf-8" - - # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters.push(:password, :password_confirmation, :private_token) - - # Enable escaping HTML in JSON. - config.active_support.escape_html_entities_in_json = true - - # Use SQL instead of Active Record's schema dumper when creating the database. - # This is necessary if your schema can't be completely dumped by the schema dumper, - # like if you have constraints or database-specific column types - # config.active_record.schema_format = :sql - - # Enable the asset pipeline - config.assets.enabled = true - config.assets.paths << Emoji.images_path - config.assets.precompile << "emoji/*.png" - config.assets.precompile << "print.css" - - # Version of your assets, change this if you want to expire all your assets - config.assets.version = '1.0' - - config.action_view.sanitized_allowed_protocols = %w(smb) - - # Relative url support - # Uncomment and customize the last line to run in a non-root path - # WARNING: We recommend creating a FQDN to host GitLab in a root path instead of this. - # Note that following settings need to be changed for this to work. - # 1) In your application.rb file: config.relative_url_root = "/gitlab" - # 2) In your gitlab.yml file: relative_url_root: /gitlab - # 3) In your unicorn.rb: ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" - # 4) In ../gitlab-shell/config.yml: gitlab_url: "http://127.0.0.1/gitlab" - # 5) In lib/support/nginx/gitlab : do not use asset gzipping, remove block starting with "location ~ ^/(assets)/" - # - # To update the path, run: sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production - # - # config.relative_url_root = "/gitlab" - - config.middleware.use Rack::Attack - - # Allow access to GitLab API from other domains - config.middleware.use Rack::Cors do - allow do - origins '*' - resource '/api/*', - headers: :any, - methods: [:get, :post, :options, :put, :delete], - expose: ['Link'] - end - end - - # Use Redis caching across all environments - redis_config_file = Rails.root.join('config', 'resque.yml') - - redis_url_string = if File.exists?(redis_config_file) - YAML.load_file(redis_config_file)[Rails.env] - else - "redis://localhost:6379" - end - - # Redis::Store does not handle Unix sockets well, so let's do it for them - redis_config_hash = Redis::Store::Factory.extract_host_options_from_uri(redis_url_string) - redis_uri = URI.parse(redis_url_string) - if redis_uri.scheme == 'unix' - redis_config_hash[:path] = redis_uri.path - end - - redis_config_hash[:namespace] = 'cache:gitlab' - config.cache_store = :redis_store, redis_config_hash - - # This is needed for gitlab-shell - ENV['GITLAB_PATH_OUTSIDE_HOOK'] = ENV['PATH'] - end -end diff --git a/config/aws.yml.example b/config/aws.yml.example deleted file mode 100644 index 29d029b078d6eb3271f84212cd6493bc7b2f8765..0000000000000000000000000000000000000000 --- a/config/aws.yml.example +++ /dev/null @@ -1,19 +0,0 @@ -# See https://github.com/jnicklas/carrierwave#using-amazon-s3 -# for more options -production: - access_key_id: AKIA1111111111111UA - secret_access_key: secret - bucket: mygitlab.production.us - region: us-east-1 - -development: - access_key_id: AKIA1111111111111UA - secret_access_key: secret - bucket: mygitlab.development.us - region: us-east-1 - -test: - access_key_id: AKIA1111111111111UA - secret_access_key: secret - bucket: mygitlab.test.us - region: us-east-1 diff --git a/config/boot.rb b/config/boot.rb deleted file mode 100644 index 4489e58688ca642d8e0e9489f6896f49f9b89da6..0000000000000000000000000000000000000000 --- a/config/boot.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'rubygems' - -# Set up gems listed in the Gemfile. -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) - -require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) diff --git a/config/database.yml.mysql b/config/database.yml.mysql deleted file mode 100644 index a99c50706c511a62a71e719bf35f3cc0dcf0625a..0000000000000000000000000000000000000000 --- a/config/database.yml.mysql +++ /dev/null @@ -1,42 +0,0 @@ -# -# PRODUCTION -# -production: - adapter: mysql2 - encoding: utf8 - collation: utf8_general_ci - reconnect: false - database: gitlabhq_production - pool: 10 - username: git - password: "secure password" - # host: localhost - # socket: /tmp/mysql.sock - -# -# Development specific -# -development: - adapter: mysql2 - encoding: utf8 - collation: utf8_general_ci - reconnect: false - database: gitlabhq_development - pool: 5 - username: root - password: "secure password" - # socket: /tmp/mysql.sock - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: &test - adapter: mysql2 - encoding: utf8 - collation: utf8_general_ci - reconnect: false - database: gitlabhq_test - pool: 5 - username: root - password: - # socket: /tmp/mysql.sock diff --git a/config/database.yml.postgresql b/config/database.yml.postgresql deleted file mode 100644 index 7067e0fe402ca956d0a644f201990db673809d67..0000000000000000000000000000000000000000 --- a/config/database.yml.postgresql +++ /dev/null @@ -1,45 +0,0 @@ -# -# PRODUCTION -# -production: - adapter: postgresql - encoding: unicode - database: gitlabhq_production - pool: 10 - # username: git - # password: - # host: localhost - # port: 5432 - -# -# Development specific -# -development: - adapter: postgresql - encoding: unicode - database: gitlabhq_development - pool: 5 - username: postgres - password: - -# -# Staging specific -# -staging: - adapter: postgresql - encoding: unicode - database: gitlabhq_staging - pool: 5 - username: postgres - password: - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: &test - adapter: postgresql - encoding: unicode - database: gitlabhq_test - pool: 5 - username: postgres - password: diff --git a/config/environment.rb b/config/environment.rb deleted file mode 100644 index 3b186a9d57afddfdae94306877719d2b98ea1945..0000000000000000000000000000000000000000 --- a/config/environment.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Load the rails application -require File.expand_path('../application', __FILE__) - -# Initialize the rails application -Gitlab::Application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb deleted file mode 100644 index 03af7f078648d3bf133ef61d277d543020ae2c8b..0000000000000000000000000000000000000000 --- a/config/environments/development.rb +++ /dev/null @@ -1,34 +0,0 @@ -Gitlab::Application.configure do - # Settings specified here will take precedence over those in config/application.rb - - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development - # since you don't have to restart the web server when you make code changes. - config.cache_classes = false - - # Show full error reports and disable caching - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Don't care if the mailer can't send - config.action_mailer.raise_delivery_errors = false - - # Print deprecation notices to the Rails logger - config.active_support.deprecation = :log - - # Only use best-standards-support built into browsers - config.action_dispatch.best_standards_support = :builtin - - # Do not compress assets - config.assets.compress = false - - # Expands the lines which load the assets - # config.assets.debug = true - - # For having correct urls in mails - config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } - # Open sent mails in browser - config.action_mailer.delivery_method = :letter_opener - - config.eager_load = false -end diff --git a/config/environments/production.rb b/config/environments/production.rb deleted file mode 100644 index 3316ece387398bf8188c9a5fb0aee12315483f50..0000000000000000000000000000000000000000 --- a/config/environments/production.rb +++ /dev/null @@ -1,80 +0,0 @@ -Gitlab::Application.configure do - # Settings specified here will take precedence over those in config/application.rb - - # Code is not reloaded between requests - config.cache_classes = true - - # Full error reports are disabled and caching is turned on - config.consider_all_requests_local = false - config.action_controller.perform_caching = true - - # Disable Rails's static asset server (Apache or nginx will already do this) - config.serve_static_assets = false - - # Compress JavaScripts and CSS. - config.assets.js_compressor = :uglifier - # config.assets.css_compressor = :sass - - # Don't fallback to assets pipeline if a precompiled asset is missed - config.assets.compile = true - - # Generate digests for assets URLs - config.assets.digest = true - - # Defaults to nil and saved in location specified by config.assets.prefix - # config.assets.manifest = YOUR_PATH - - # Specifies the header that your server uses for sending files - # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx - - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - # config.force_ssl = true - - # See everything in the log (default is :info) - # config.log_level = :debug - - # Suppress 'Rendered template ...' messages in the log - # source: http://stackoverflow.com/a/16369363 - %w{render_template render_partial render_collection}.each do |event| - ActiveSupport::Notifications.unsubscribe "#{event}.action_view" - end - - # Prepend all log lines with the following tags - # config.log_tags = [ :subdomain, :uuid ] - - # Use a different logger for distributed setups - # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) - - # Enable serving of images, stylesheets, and JavaScripts from an asset server - # config.action_controller.asset_host = "http://assets.example.com" - - # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) - # config.assets.precompile += %w( search.js ) - - # Disable delivery errors, bad email addresses will be ignored - # config.action_mailer.raise_delivery_errors = false - - # Enable threaded mode - # config.threadsafe! unless $rails_rake_task - - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation can not be found) - config.i18n.fallbacks = true - - # Send deprecation notices to registered listeners - config.active_support.deprecation = :notify - - config.action_mailer.delivery_method = :sendmail - # Defaults to: - # # config.action_mailer.sendmail_settings = { - # # location: '/usr/sbin/sendmail', - # # arguments: '-i -t' - # # } - config.action_mailer.perform_deliveries = true - config.action_mailer.raise_delivery_errors = true - - config.eager_load = true - - config.allow_concurrency = false -end diff --git a/config/environments/test.rb b/config/environments/test.rb deleted file mode 100644 index 2d5e7addcd3ebe1b6d3dc5661e962c6790415370..0000000000000000000000000000000000000000 --- a/config/environments/test.rb +++ /dev/null @@ -1,33 +0,0 @@ -Gitlab::Application.configure do - # Settings specified here will take precedence over those in config/application.rb - - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! - config.cache_classes = false - - # Configure static asset server for tests with Cache-Control for performance - config.serve_static_assets = true - config.static_cache_control = "public, max-age=3600" - - # Show full error reports and disable caching - config.consider_all_requests_local = true - config.action_controller.perform_caching = false - - # Raise exceptions instead of rendering exception templates - config.action_dispatch.show_exceptions = false - - # Disable request forgery protection in test environment - config.action_controller.allow_forgery_protection = false - - # Tell Action Mailer not to deliver emails to the real world. - # The :test delivery method accumulates sent emails in the - # ActionMailer::Base.deliveries array. - config.action_mailer.delivery_method = :test - - # Print deprecation notices to the stderr - config.active_support.deprecation = :stderr - - config.eager_load = false -end diff --git a/config/gitlab.teatro.yml b/config/gitlab.teatro.yml deleted file mode 100644 index f0656400beb00c2dc9fc82bc2be41235a9504340..0000000000000000000000000000000000000000 --- a/config/gitlab.teatro.yml +++ /dev/null @@ -1,86 +0,0 @@ - -production: &base - gitlab: - host: localhost - port: 80 - https: false - - user: root - - email_from: example@example.com - - support_email: support@example.com - - default_projects_features: - issues: true - merge_requests: true - wiki: true - wall: false - snippets: false - visibility_level: "private" # can be "private" | "internal" | "public" - - issues_tracker: - - gravatar: - enabled: true # Use user avatar image from Gravatar.com (default: true) - - ldap: - enabled: false - host: '_your_ldap_server' - port: 636 - uid: 'sAMAccountName' - method: 'ssl' # "tls" or "ssl" or "plain" - bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' - password: '_the_password_of_the_bind_user' - allow_username_or_email_login: true - - base: '' - - user_filter: '' - - omniauth: - enabled: false - - satellites: - # Relative paths are relative to Rails.root (default: tmp/repo_satellites/) - path: /apps/gitlab-satellites/ - - backup: - path: "tmp/backups" # Relative paths are relative to Rails.root (default: tmp/backups/) - - gitlab_shell: - path: /apps/gitlab-shell/ - - # REPOS_PATH MUST NOT BE A SYMLINK!!! - repos_path: /apps/repositories/ - hooks_path: /apps/gitlab-shell/hooks/ - - upload_pack: true - receive_pack: true - - git: - bin_path: /usr/bin/git - max_size: 5242880 # 5.megabytes - timeout: 10 - - extra: - -development: - <<: *base - -test: - <<: *base - gravatar: - enabled: true - gitlab: - host: localhost - port: 80 - issues_tracker: - redmine: - title: "Redmine" - project_url: "http://redmine/projects/:issues_tracker_id" - issues_url: "http://redmine/:project_id/:issues_tracker_id/:id" - new_issue_url: "http://redmine/projects/:issues_tracker_id/issues/new" - -staging: - <<: *base diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example deleted file mode 100644 index ba40671b162cd36e320de9012ac0242da9d286eb..0000000000000000000000000000000000000000 --- a/config/gitlab.yml.example +++ /dev/null @@ -1,337 +0,0 @@ -# # # # # # # # # # # # # # # # # # -# GitLab application config file # -# # # # # # # # # # # # # # # # # # -# -########################### NOTE ##################################### -# This file should not receive new settings. All configuration options # -# are being moved to ApplicationSetting model! # -######################################################################## -# -# How to use: -# 1. Copy file as gitlab.yml -# 2. Update gitlab -> host with your fully qualified domain name -# 3. Update gitlab -> email_from -# 4. If you installed Git from source, change git -> bin_path to /usr/local/bin/git -# 5. Review this configuration file for other settings you may want to adjust - -production: &base - # - # 1. GitLab app settings - # ========================== - - ## GitLab settings - gitlab: - ## Web server settings (note: host is the FQDN, do not include http://) - host: localhost - port: 80 # Set to 443 if using HTTPS, see installation.md#using-https for additional HTTPS configuration details - https: false # Set to true if using HTTPS, see installation.md#using-https for additional HTTPS configuration details - - # Uncommment this line below if your ssh host is different from HTTP/HTTPS one - # (you'd obviously need to replace ssh.host_example.com with your own host). - # Otherwise, ssh host will be set to the `host:` value above - # ssh_host: ssh.host_example.com - - # WARNING: See config/application.rb under "Relative url support" for the list of - # other files that need to be changed for relative url support - # relative_url_root: /gitlab - - # Uncomment and customize if you can't use the default user to run GitLab (default: 'git') - # user: git - - ## Date & Time settings - # Uncomment and customize if you want to change the default time zone of GitLab application. - # To see all available zones, run `bundle exec rake time:zones:all RAILS_ENV=production` - # time_zone: 'UTC' - - ## Email settings - # Uncomment and set to false if you need to disable email sending from GitLab (default: true) - # email_enabled: true - # Email address used in the "From" field in mails sent by GitLab - email_from: example@example.com - email_display_name: GitLab - email_reply_to: noreply@example.com - - # Email server smtp settings are in config/initializers/smtp_settings.rb.sample - - # default_can_create_group: false # default: true - # username_changing_enabled: false # default: true - User can change her username/namespace - ## Default theme - ## BASIC = 1 - ## MARS = 2 - ## MODERN = 3 - ## GRAY = 4 - ## COLOR = 5 - # default_theme: 2 # default: 2 - - ## Automatic issue closing - # If a commit message matches this regular expression, all issues referenced from the matched text will be closed. - # This happens when the commit is pushed or merged into the default branch of a project. - # When not specified the default issue_closing_pattern as specified below will be used. - # Tip: you can test your closing pattern at http://rubular.com. - # issue_closing_pattern: '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' - - ## Default project features settings - default_projects_features: - issues: true - merge_requests: true - wiki: true - snippets: false - visibility_level: "private" # can be "private" | "internal" | "public" - - ## Webhook settings - # Number of seconds to wait for HTTP response after sending webhook HTTP POST request (default: 10) - # webhook_timeout: 10 - - ## Repository downloads directory - # When a user clicks e.g. 'Download zip' on a project, a temporary zip file is created in the following directory. - # The default is 'tmp/repositories' relative to the root of the Rails app. - # repository_downloads_path: tmp/repositories - - ## Gravatar - ## For Libravatar see: http://doc.gitlab.com/ce/customization/libravatar.html - gravatar: - enabled: true # Use user avatar image from Gravatar.com (default: true) - # gravatar urls: possible placeholders: %{hash} %{size} %{email} - # plain_url: "http://..." # default: http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon - # ssl_url: "https://..." # default: https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon - - # - # 2. Auth settings - # ========================== - - ## LDAP settings - # You can inspect a sample of the LDAP users with login access by running: - # bundle exec rake gitlab:ldap:check RAILS_ENV=production - ldap: - enabled: false - servers: - ########################################################################## - # - # Since GitLab 7.4, LDAP servers get ID's (below the ID is 'main'). GitLab - # Enterprise Edition now supports connecting to multiple LDAP servers. - # - # If you are updating from the old (pre-7.4) syntax, you MUST give your - # old server the ID 'main'. - # - ########################################################################## - main: # 'main' is the GitLab 'provider ID' of this LDAP server - ## label - # - # A human-friendly name for your LDAP server. It is OK to change the label later, - # for instance if you find out it is too large to fit on the web page. - # - # Example: 'Paris' or 'Acme, Ltd.' - label: 'LDAP' - - host: '_your_ldap_server' - port: 389 - uid: 'sAMAccountName' - method: 'plain' # "tls" or "ssl" or "plain" - bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' - password: '_the_password_of_the_bind_user' - - # This setting specifies if LDAP server is Active Directory LDAP server. - # For non AD servers it skips the AD specific queries. - # If your LDAP server is not AD, set this to false. - active_directory: true - - # If allow_username_or_email_login is enabled, GitLab will ignore everything - # after the first '@' in the LDAP username submitted by the user on login. - # - # Example: - # - the user enters 'jane.doe@example.com' and 'p@ssw0rd' as LDAP credentials; - # - GitLab queries the LDAP server with 'jane.doe' and 'p@ssw0rd'. - # - # If you are using "uid: 'userPrincipalName'" on ActiveDirectory you need to - # disable this setting, because the userPrincipalName contains an '@'. - allow_username_or_email_login: false - - # To maintain tight control over the number of active users on your GitLab installation, - # enable this setting to keep new users blocked until they have been cleared by the admin - # (default: false). - block_auto_created_users: false - - # Base where we can search for users - # - # Ex. ou=People,dc=gitlab,dc=example - # - base: '' - - # Filter LDAP users - # - # Format: RFC 4515 http://tools.ietf.org/search/rfc4515 - # Ex. (employeeType=developer) - # - # Note: GitLab does not support omniauth-ldap's custom filter syntax. - # - user_filter: '' - - # GitLab EE only: add more LDAP servers - # Choose an ID made of a-z and 0-9 . This ID will be stored in the database - # so that GitLab can remember which LDAP server a user belongs to. - # uswest2: - # label: - # host: - # .... - - - ## OmniAuth settings - omniauth: - # Allow login via Twitter, Google, etc. using OmniAuth providers - enabled: false - - # CAUTION! - # This allows users to login without having a user account first (default: false). - # User accounts will be created automatically when authentication was successful. - allow_single_sign_on: false - # Locks down those users until they have been cleared by the admin (default: true). - block_auto_created_users: true - - ## Auth providers - # Uncomment the following lines and fill in the data of the auth provider you want to use - # If your favorite auth provider is not listed you can use others: - # see https://github.com/gitlabhq/gitlab-public-wiki/wiki/Custom-omniauth-provider-configurations - # The 'app_id' and 'app_secret' parameters are always passed as the first two - # arguments, followed by optional 'args' which can be either a hash or an array. - # Documentation for this is available at http://doc.gitlab.com/ce/integration/omniauth.html - providers: - # - { name: 'google_oauth2', app_id: 'YOUR_APP_ID', - # app_secret: 'YOUR_APP_SECRET', - # args: { access_type: 'offline', approval_prompt: '' } } - # - { name: 'twitter', app_id: 'YOUR_APP_ID', - # app_secret: 'YOUR_APP_SECRET'} - # - { name: 'github', app_id: 'YOUR_APP_ID', - # app_secret: 'YOUR_APP_SECRET', - # args: { scope: 'user:email' } } - # - { name: 'gitlab', app_id: 'YOUR_APP_ID', - # app_secret: 'YOUR_APP_SECRET', - # args: { scope: 'api' } } - # - { name: 'bitbucket', app_id: 'YOUR_APP_ID', - # app_secret: 'YOUR_APP_SECRET'} - - - - # - # 3. Advanced settings - # ========================== - - # GitLab Satellites - satellites: - # Relative paths are relative to Rails.root (default: tmp/repo_satellites/) - path: /home/git/gitlab-satellites/ - timeout: 30 - - ## Backup settings - backup: - path: "tmp/backups" # Relative paths are relative to Rails.root (default: tmp/backups/) - # keep_time: 604800 # default: 0 (forever) (in seconds) - # upload: - # # Fog storage connection settings, see http://fog.io/storage/ . - # connection: - # provider: AWS - # region: eu-west-1 - # aws_access_key_id: AKIAKIAKI - # aws_secret_access_key: 'secret123' - # # The remote 'directory' to store your backups. For S3, this would be the bucket name. - # remote_directory: 'my.s3.bucket' - - ## GitLab Shell settings - gitlab_shell: - path: /home/git/gitlab-shell/ - - # REPOS_PATH MUST NOT BE A SYMLINK!!! - repos_path: /home/git/repositories/ - hooks_path: /home/git/gitlab-shell/hooks/ - - # Git over HTTP - upload_pack: true - receive_pack: true - - # If you use non-standard ssh port you need to specify it - # ssh_port: 22 - - ## Git settings - # CAUTION! - # Use the default values unless you really know what you are doing - git: - bin_path: /usr/bin/git - # The next value is the maximum memory size grit can use - # Given in number of bytes per git object (e.g. a commit) - # This value can be increased if you have very large commits - max_size: 20971520 # 20.megabytes - # Git timeout to read a commit, in seconds - timeout: 10 - - # - # 4. Extra customization - # ========================== - - extra: - ## Google analytics. Uncomment if you want it - # google_analytics_id: '_your_tracking_id' - - ## Piwik analytics. - # piwik_url: '_your_piwik_url' - # piwik_site_id: '_your_piwik_site_id' - - rack_attack: - git_basic_auth: - # Rack Attack IP banning enabled - # enabled: true - # - # Whitelist requests from 127.0.0.1 for web proxies (NGINX/Apache) with incorrect headers - # ip_whitelist: ["127.0.0.1"] - # - # Limit the number of Git HTTP authentication attempts per IP - # maxretry: 10 - # - # Reset the auth attempt counter per IP after 60 seconds - # findtime: 60 - # - # Ban an IP for one hour (3600s) after too many auth attempts - # bantime: 3600 - -development: - <<: *base - -test: - <<: *base - gravatar: - enabled: true - gitlab: - host: localhost - port: 80 - - # When you run tests we clone and setup gitlab-shell - # In order to setup it correctly you need to specify - # your system username you use to run GitLab - # user: YOUR_USERNAME - satellites: - path: tmp/tests/gitlab-satellites/ - gitlab_shell: - path: tmp/tests/gitlab-shell/ - repos_path: tmp/tests/repositories/ - hooks_path: tmp/tests/gitlab-shell/hooks/ - issues_tracker: - redmine: - title: "Redmine" - project_url: "http://redmine/projects/:issues_tracker_id" - issues_url: "http://redmine/:project_id/:issues_tracker_id/:id" - new_issue_url: "http://redmine/projects/:issues_tracker_id/issues/new" - ldap: - enabled: false - servers: - main: - label: ldap - host: 127.0.0.1 - port: 3890 - uid: 'uid' - method: 'plain' # "tls" or "ssl" or "plain" - base: 'dc=example,dc=com' - user_filter: '' - group_base: 'ou=groups,dc=example,dc=com' - admin_group: '' - sync_ssh_keys: false - -staging: - <<: *base diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb deleted file mode 100644 index 0abd34fc3e0a013e729418084e0b2a89e5750e22..0000000000000000000000000000000000000000 --- a/config/initializers/1_settings.rb +++ /dev/null @@ -1,206 +0,0 @@ -require 'gitlab' # Load lib/gitlab.rb as soon as possible - -class Settings < Settingslogic - source ENV.fetch('GITLAB_CONFIG') { "#{Rails.root}/config/gitlab.yml" } - namespace Rails.env - - class << self - def gitlab_on_standard_port? - gitlab.port.to_i == (gitlab.https ? 443 : 80) - end - - private - - def build_gitlab_shell_ssh_path_prefix - if gitlab_shell.ssh_port != 22 - "ssh://#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}:#{gitlab_shell.ssh_port}/" - else - if gitlab_shell.ssh_host.include? ':' - "[#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}]:" - else - "#{gitlab_shell.ssh_user}@#{gitlab_shell.ssh_host}:" - end - end - end - - def build_gitlab_url - custom_port = gitlab_on_standard_port? ? nil : ":#{gitlab.port}" - [ gitlab.protocol, - "://", - gitlab.host, - custom_port, - gitlab.relative_url_root - ].join('') - end - - # check that values in `current` (string or integer) is a contant in `modul`. - def verify_constant_array(modul, current, default) - values = default || [] - if !current.nil? - values = [] - current.each do |constant| - values.push(verify_constant(modul, constant, nil)) - end - values.delete_if { |value| value.nil? } - end - values - end - - # check that `current` (string or integer) is a contant in `modul`. - def verify_constant(modul, current, default) - constant = modul.constants.find{ |name| modul.const_get(name) == current } - value = constant.nil? ? default : modul.const_get(constant) - if current.is_a? String - value = modul.const_get(current.upcase) rescue default - end - value - end - end -end - - -# Default settings -Settings['ldap'] ||= Settingslogic.new({}) -Settings.ldap['enabled'] = false if Settings.ldap['enabled'].nil? - -# backwards compatibility, we only have one host -if Settings.ldap['enabled'] || Rails.env.test? - if Settings.ldap['host'].present? - # We detected old LDAP configuration syntax. Update the config to make it - # look like it was entered with the new syntax. - server = Settings.ldap.except('sync_time') - Settings.ldap['servers'] = { - 'main' => server - } - end - - Settings.ldap['servers'].each do |key, server| - server['label'] ||= 'LDAP' - server['block_auto_created_users'] = false if server['block_auto_created_users'].nil? - server['allow_username_or_email_login'] = false if server['allow_username_or_email_login'].nil? - server['active_directory'] = true if server['active_directory'].nil? - server['provider_name'] ||= "ldap#{key}".downcase - server['provider_class'] = OmniAuth::Utils.camelize(server['provider_name']) - end -end - - -Settings['omniauth'] ||= Settingslogic.new({}) -Settings.omniauth['enabled'] = false if Settings.omniauth['enabled'].nil? -Settings.omniauth['providers'] ||= [] - -Settings['issues_tracker'] ||= {} - -# -# GitLab -# -Settings['gitlab'] ||= Settingslogic.new({}) -Settings.gitlab['default_projects_limit'] ||= 10 -Settings.gitlab['default_branch_protection'] ||= 2 -Settings.gitlab['default_can_create_group'] = true if Settings.gitlab['default_can_create_group'].nil? -Settings.gitlab['default_theme'] = Gitlab::Theme::MARS if Settings.gitlab['default_theme'].nil? -Settings.gitlab['host'] ||= 'localhost' -Settings.gitlab['ssh_host'] ||= Settings.gitlab.host -Settings.gitlab['https'] = false if Settings.gitlab['https'].nil? -Settings.gitlab['port'] ||= Settings.gitlab.https ? 443 : 80 -Settings.gitlab['relative_url_root'] ||= ENV['RAILS_RELATIVE_URL_ROOT'] || '' -Settings.gitlab['protocol'] ||= Settings.gitlab.https ? "https" : "http" -Settings.gitlab['email_enabled'] ||= true if Settings.gitlab['email_enabled'].nil? -Settings.gitlab['email_from'] ||= "gitlab@#{Settings.gitlab.host}" -Settings.gitlab['email_display_name'] ||= "GitLab" -Settings.gitlab['email_reply_to'] ||= "noreply@#{Settings.gitlab.host}" -Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url) -Settings.gitlab['user'] ||= 'git' -Settings.gitlab['user_home'] ||= begin - Etc.getpwnam(Settings.gitlab['user']).dir -rescue ArgumentError # no user configured - '/home/' + Settings.gitlab['user'] -end -Settings.gitlab['time_zone'] ||= nil -Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil? -Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil? -Settings.gitlab['twitter_sharing_enabled'] ||= true if Settings.gitlab['twitter_sharing_enabled'].nil? -Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], []) -Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil? -Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' if Settings.gitlab['issue_closing_pattern'].nil? -Settings.gitlab['default_projects_features'] ||= {} -Settings.gitlab['webhook_timeout'] ||= 10 -Settings.gitlab['max_attachment_size'] ||= 10 -Settings.gitlab.default_projects_features['issues'] = true if Settings.gitlab.default_projects_features['issues'].nil? -Settings.gitlab.default_projects_features['merge_requests'] = true if Settings.gitlab.default_projects_features['merge_requests'].nil? -Settings.gitlab.default_projects_features['wiki'] = true if Settings.gitlab.default_projects_features['wiki'].nil? -Settings.gitlab.default_projects_features['snippets'] = false if Settings.gitlab.default_projects_features['snippets'].nil? -Settings.gitlab.default_projects_features['visibility_level'] = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE) -Settings.gitlab['repository_downloads_path'] = File.absolute_path(Settings.gitlab['repository_downloads_path'] || 'tmp/repositories', Rails.root) - -# -# Gravatar -# -Settings['gravatar'] ||= Settingslogic.new({}) -Settings.gravatar['enabled'] = true if Settings.gravatar['enabled'].nil? -Settings.gravatar['plain_url'] ||= 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon' -Settings.gravatar['ssl_url'] ||= 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon' - -# -# GitLab Shell -# -Settings['gitlab_shell'] ||= Settingslogic.new({}) -Settings.gitlab_shell['path'] ||= Settings.gitlab['user_home'] + '/gitlab-shell/' -Settings.gitlab_shell['hooks_path'] ||= Settings.gitlab['user_home'] + '/gitlab-shell/hooks/' -Settings.gitlab_shell['receive_pack'] = true if Settings.gitlab_shell['receive_pack'].nil? -Settings.gitlab_shell['upload_pack'] = true if Settings.gitlab_shell['upload_pack'].nil? -Settings.gitlab_shell['repos_path'] ||= Settings.gitlab['user_home'] + '/repositories/' -Settings.gitlab_shell['ssh_host'] ||= Settings.gitlab.ssh_host -Settings.gitlab_shell['ssh_port'] ||= 22 -Settings.gitlab_shell['ssh_user'] ||= Settings.gitlab.user -Settings.gitlab_shell['owner_group'] ||= Settings.gitlab.user -Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_ssh_path_prefix) - -# -# Backup -# -Settings['backup'] ||= Settingslogic.new({}) -Settings.backup['keep_time'] ||= 0 -Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root) -Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil }) -# Convert upload connection settings to use symbol keys, to make Fog happy -if Settings.backup['upload']['connection'] - Settings.backup['upload']['connection'] = Hash[Settings.backup['upload']['connection'].map { |k, v| [k.to_sym, v] }] -end - -# -# Git -# -Settings['git'] ||= Settingslogic.new({}) -Settings.git['max_size'] ||= 20971520 # 20.megabytes -Settings.git['bin_path'] ||= '/usr/bin/git' -Settings.git['timeout'] ||= 10 - -Settings['satellites'] ||= Settingslogic.new({}) -Settings.satellites['path'] = File.expand_path(Settings.satellites['path'] || "tmp/repo_satellites/", Rails.root) -Settings.satellites['timeout'] ||= 30 - -# -# Extra customization -# -Settings['extra'] ||= Settingslogic.new({}) - -# -# Rack::Attack settings -# -Settings['rack_attack'] ||= Settingslogic.new({}) -Settings.rack_attack['git_basic_auth'] ||= Settingslogic.new({}) -Settings.rack_attack.git_basic_auth['enabled'] = true if Settings.rack_attack.git_basic_auth['enabled'].nil? -Settings.rack_attack.git_basic_auth['ip_whitelist'] ||= %w{127.0.0.1} -Settings.rack_attack.git_basic_auth['maxretry'] ||= 10 -Settings.rack_attack.git_basic_auth['findtime'] ||= 1.minute -Settings.rack_attack.git_basic_auth['bantime'] ||= 1.hour - -# -# Testing settings -# -if Rails.env.test? - Settings.gitlab['default_projects_limit'] = 42 - Settings.gitlab['default_can_create_group'] = true - Settings.gitlab['default_can_create_team'] = false -end diff --git a/config/initializers/2_app.rb b/config/initializers/2_app.rb deleted file mode 100644 index 688cdf5f4b0887eb23bcdfdf41a2c51719eb329b..0000000000000000000000000000000000000000 --- a/config/initializers/2_app.rb +++ /dev/null @@ -1,8 +0,0 @@ -module Gitlab - VERSION = File.read(Rails.root.join("VERSION")).strip - REVISION = Gitlab::Popen.popen(%W(git log --pretty=format:%h -n 1)).first.chomp - - def self.config - Settings - end -end diff --git a/config/initializers/3_grit_ext.rb b/config/initializers/3_grit_ext.rb deleted file mode 100644 index 6540ac839cb1e5242678ee25b35b129c4bee8237..0000000000000000000000000000000000000000 --- a/config/initializers/3_grit_ext.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'grit' - -Grit::Git.git_binary = Gitlab.config.git.bin_path -Grit::Git.git_timeout = Gitlab.config.git.timeout -Grit::Git.git_max_size = Gitlab.config.git.max_size diff --git a/config/initializers/4_sidekiq.rb b/config/initializers/4_sidekiq.rb deleted file mode 100644 index e856499732e949334e401a6740846f1d706ba24b..0000000000000000000000000000000000000000 --- a/config/initializers/4_sidekiq.rb +++ /dev/null @@ -1,27 +0,0 @@ -# Custom Redis configuration -config_file = Rails.root.join('config', 'resque.yml') - -resque_url = if File.exists?(config_file) - YAML.load_file(config_file)[Rails.env] - else - "redis://localhost:6379" - end - -Sidekiq.configure_server do |config| - config.redis = { - url: resque_url, - namespace: 'resque:gitlab' - } - - config.server_middleware do |chain| - chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger if ENV['SIDEKIQ_LOG_ARGUMENTS'] - chain.add Gitlab::SidekiqMiddleware::MemoryKiller if ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS'] - end -end - -Sidekiq.configure_client do |config| - config.redis = { - url: resque_url, - namespace: 'resque:gitlab' - } -end diff --git a/config/initializers/5_backend.rb b/config/initializers/5_backend.rb deleted file mode 100644 index 80d641d73a37ae8d385131711095ccfcb3542412..0000000000000000000000000000000000000000 --- a/config/initializers/5_backend.rb +++ /dev/null @@ -1,15 +0,0 @@ -# GIT over HTTP -require Rails.root.join("lib", "gitlab", "backend", "grack_auth") - -# GIT over SSH -require Rails.root.join("lib", "gitlab", "backend", "shell") - -# GitLab shell adapter -require Rails.root.join("lib", "gitlab", "backend", "shell_adapter") - -required_version = Gitlab::VersionInfo.parse(Gitlab::Shell.version_required) -current_version = Gitlab::VersionInfo.parse(Gitlab::Shell.new.version) - -unless current_version.valid? && required_version <= current_version - warn "WARNING: This version of GitLab depends on gitlab-shell #{required_version}, but you're running #{current_version}. Please update gitlab-shell." -end diff --git a/config/initializers/6_rack_profiler.rb b/config/initializers/6_rack_profiler.rb deleted file mode 100644 index b634028756925661e59683bd908b5140275504ef..0000000000000000000000000000000000000000 --- a/config/initializers/6_rack_profiler.rb +++ /dev/null @@ -1,8 +0,0 @@ -if Rails.env == 'development' - require 'rack-mini-profiler' - - # initialization is skipped so trigger it - Rack::MiniProfilerRails.initialize!(Rails.application) - Rack::MiniProfiler.config.position = 'right' - Rack::MiniProfiler.config.start_hidden = true -end diff --git a/config/initializers/7_omniauth.rb b/config/initializers/7_omniauth.rb deleted file mode 100644 index 8f6c5673103de9d4feea06b2b42be6aa37130120..0000000000000000000000000000000000000000 --- a/config/initializers/7_omniauth.rb +++ /dev/null @@ -1,12 +0,0 @@ -if Gitlab::LDAP::Config.enabled? - module OmniAuth::Strategies - server = Gitlab.config.ldap.servers.values.first - klass = server['provider_class'] - const_set(klass, Class.new(LDAP)) unless klass == 'LDAP' - end - - OmniauthCallbacksController.class_eval do - server = Gitlab.config.ldap.servers.values.first - alias_method server['provider_name'], :ldap - end -end diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb deleted file mode 100644 index 59385cdf379bd06a8d2326dcd4de6d5cd5d3f5b0..0000000000000000000000000000000000000000 --- a/config/initializers/backtrace_silencers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. -# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } - -# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. -# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb deleted file mode 100644 index bfb8656df552da088bf7848deaa77540945bead2..0000000000000000000000000000000000000000 --- a/config/initializers/carrierwave.rb +++ /dev/null @@ -1,41 +0,0 @@ -CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/ - -aws_file = Rails.root.join('config', 'aws.yml') - -if File.exists?(aws_file) - AWS_CONFIG = YAML.load(File.read(aws_file))[Rails.env] - - CarrierWave.configure do |config| - config.fog_credentials = { - provider: 'AWS', # required - aws_access_key_id: AWS_CONFIG['access_key_id'], # required - aws_secret_access_key: AWS_CONFIG['secret_access_key'], # required - region: AWS_CONFIG['region'], # optional, defaults to 'us-east-1' - } - - # required - config.fog_directory = AWS_CONFIG['bucket'] - - # optional, defaults to true - config.fog_public = false - - # optional, defaults to {} - config.fog_attributes = { 'Cache-Control'=>'max-age=315576000' } - - # optional time (in seconds) that authenticated urls will be valid. - # when fog_public is false and provider is AWS or Google, defaults to 600 - config.fog_authenticated_url_expiration = 1 << 29 - end - - # Mocking Fog requests, based on: https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Test-Fog-based-uploaders - if Rails.env.test? - Fog.mock! - connection = ::Fog::Storage.new( - aws_access_key_id: AWS_CONFIG['access_key_id'], - aws_secret_access_key: AWS_CONFIG['secret_access_key'], - provider: 'AWS', - region: AWS_CONFIG['region'] - ) - connection.directories.create(key: AWS_CONFIG['bucket']) - end -end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb deleted file mode 100644 index 9dce495106f50cd4167eb3c4e4aa941aad6f8f66..0000000000000000000000000000000000000000 --- a/config/initializers/devise.rb +++ /dev/null @@ -1,246 +0,0 @@ -# Use this hook to configure devise mailer, warden hooks and so forth. The first -# four configuration values can also be set straight in your models. -Devise.setup do |config| - # ==> Mailer Configuration - # Configure the e-mail address which will be shown in Devise::Mailer, - # note that it will be overwritten if you use your own mailer class with default "from" parameter. - config.mailer_sender = "GitLab <#{Gitlab.config.gitlab.email_from}>" - - - # Configure the class responsible to send e-mails. - # config.mailer = "Devise::Mailer" - - # ==> ORM configuration - # Load and configure the ORM. Supports :active_record (default) and - # :mongoid (bson_ext recommended) by default. Other ORMs may be - # available as additional gems. - require 'devise/orm/active_record' - - # ==> Configuration for any authentication mechanism - # Configure which keys are used when authenticating a user. The default is - # just :email. You can configure it to use [:username, :subdomain], so for - # authenticating a user, both parameters are required. Remember that those - # parameters are used only when authenticating and not when retrieving from - # session. If you need permissions, you should implement that in a before filter. - # You can also supply a hash where the value is a boolean determining whether - # or not authentication should be aborted when the value is not present. - config.authentication_keys = [ :login ] - - # Configure parameters from the request object used for authentication. Each entry - # given should be a request method and it will automatically be passed to the - # find_for_authentication method and considered in your model lookup. For instance, - # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. - # The same considerations mentioned for authentication_keys also apply to request_keys. - # config.request_keys = [] - - # Configure which authentication keys should be case-insensitive. - # These keys will be downcased upon creating or modifying a user and when used - # to authenticate or find a user. Default is :email. - config.case_insensitive_keys = [ :email ] - - # Configure which authentication keys should have whitespace stripped. - # These keys will have whitespace before and after removed upon creating or - # modifying a user and when used to authenticate or find a user. Default is :email. - config.strip_whitespace_keys = [ :email ] - - # Tell if authentication through request.params is enabled. True by default. - # config.params_authenticatable = true - - # Tell if authentication through HTTP Basic Auth is enabled. False by default. - # config.http_authenticatable = false - - # If http headers should be returned for AJAX requests. True by default. - # config.http_authenticatable_on_xhr = true - - # The realm used in Http Basic Authentication. "Application" by default. - # config.http_authentication_realm = "Application" - - config.reconfirmable = true - - # It will change confirmation, password recovery and other workflows - # to behave the same regardless if the e-mail provided was right or wrong. - # Does not affect registerable. - # config.paranoid = true - - # ==> Configuration for :database_authenticatable - # For bcrypt, this is the cost for hashing the password and defaults to 10. If - # using other encryptors, it sets how many times you want the password re-encrypted. - # - # Limiting the stretches to just one in testing will increase the performance of - # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use - # a value less than 10 in other environments. - config.stretches = Rails.env.test? ? 1 : 10 - - # Setup a pepper to generate the encrypted password. - # config.pepper = "2ef62d549c4ff98a5d3e0ba211e72cff592060247e3bbbb9f499af1222f876f53d39b39b823132affb32858168c79c1d7741d26499901b63c6030a42129924ef" - - # ==> Configuration for :confirmable - # The time you want to give a user to confirm their account. During this time - # they will be able to access your application without confirming. Default is 0.days - # When allow_unconfirmed_access_for is zero, the user won't be able to sign in without confirming. - # You can use this to let your user access some features of your application - # without confirming the account, but blocking it after a certain period - # (ie 2 days). - # config.allow_unconfirmed_access_for = 2.days - - # Defines which key will be used when confirming an account - # config.confirmation_keys = [ :email ] - - # ==> Configuration for :rememberable - # The time the user will be remembered without asking for credentials again. - # config.remember_for = 2.weeks - - # If true, a valid remember token can be re-used between multiple browsers. - # config.remember_across_browsers = true - - # If true, extends the user's remember period when remembered via cookie. - # config.extend_remember_period = false - - # Options to be passed to the created cookie. For instance, you can set - # secure: true in order to force SSL only cookies. - # config.cookie_options = {} - - # ==> Configuration for :validatable - # Range for password length. Default is 6..128. - config.password_length = 8..128 - - # Email regex used to validate email formats. It simply asserts that - # an one (and only one) @ exists in the given string. This is mainly - # to give user feedback and not to assert the e-mail validity. - # config.email_regexp = /\A[^@]+@[^@]+\z/ - - # ==> Configuration for :timeoutable - # The time you want to timeout the user session without activity. After this - # time the user will be asked for credentials again. Default is 30 minutes. - # config.timeout_in = 30.minutes - - # ==> Configuration for :lockable - # Defines which strategy will be used to lock an account. - # :failed_attempts = Locks an account after a number of failed attempts to sign in. - # :none = No lock strategy. You should handle locking by yourself. - config.lock_strategy = :failed_attempts - - # Defines which key will be used when locking and unlocking an account - # config.unlock_keys = [ :email ] - - # Defines which strategy will be used to unlock an account. - # :email = Sends an unlock link to the user email - # :time = Re-enables login after a certain amount of time (see :unlock_in below) - # :both = Enables both strategies - # :none = No unlock strategy. You should handle unlocking by yourself. - config.unlock_strategy = :time - - # Number of authentication tries before locking an account if lock_strategy - # is failed attempts. - config.maximum_attempts = 10 - - # Time interval to unlock the account if :time is enabled as unlock_strategy. - config.unlock_in = 10.minutes - - # ==> Configuration for :recoverable - # - # Defines which key will be used when recovering the password for an account - # config.reset_password_keys = [ :email ] - - # Time interval you can reset your password with a reset password key. - # Don't put a too small interval or your users won't have the time to - # change their passwords. - # When someone else invites you to GitLab this time is also used so it should be pretty long. - config.reset_password_within = 2.days - - # ==> Configuration for :encryptable - # Allow you to use another encryption algorithm besides bcrypt (default). You can use - # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, - # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) - # and :restful_authentication_sha1 (then you should set stretches to 10, and copy - # REST_AUTH_SITE_KEY to pepper) - # config.encryptor = :sha512 - - # Authentication through token does not store user in session and needs - # to be supplied on each request. Useful if you are using the token as API token. - config.skip_session_storage << :token_auth - - # ==> Scopes configuration - # Turn scoped views on. Before rendering "sessions/new", it will first check for - # "users/sessions/new". It's turned off by default because it's slower if you - # are using only default views. - # config.scoped_views = false - - # Configure the default scope given to Warden. By default it's the first - # devise role declared in your routes (usually :user). - # config.default_scope = :user - - # Configure sign_out behavior. - # Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope). - # The default is true, which means any logout action will sign out all active scopes. - # config.sign_out_all_scopes = true - - # ==> Navigation configuration - # Lists the formats that should be treated as navigational. Formats like - # :html, should redirect to the sign in page when the user does not have - # access, but formats like :xml or :json, should return 401. - # - # If you have any extra navigational formats, like :iphone or :mobile, you - # should add them to the navigational formats lists. - # - # The :"*/*" and "*/*" formats below is required to match Internet - # Explorer requests. - # config.navigational_formats = [:"*/*", "*/*", :html] - - # The default HTTP method used to sign out a resource. Default is :delete. - config.sign_out_via = :delete - - # ==> OmniAuth - # To configure a new OmniAuth provider copy and edit omniauth.rb.sample - # selecting the provider you require. - # Check the wiki for more information on setting up on your models - - # ==> Warden configuration - # If you want to use other strategies, that are not supported by Devise, or - # change the failure app, you can configure them inside the config.warden block. - # - # config.warden do |manager| - # manager.failure_app = AnotherApp - # manager.intercept_401 = false - # manager.default_strategies(scope: :user).unshift :some_external_strategy - # end - - if Gitlab::LDAP::Config.enabled? - Gitlab.config.ldap.servers.values.each do |server| - if server['allow_username_or_email_login'] - email_stripping_proc = ->(name) {name.gsub(/@.*\z/,'')} - else - email_stripping_proc = ->(name) {name} - end - - config.omniauth server['provider_name'], - host: server['host'], - base: server['base'], - uid: server['uid'], - port: server['port'], - method: server['method'], - bind_dn: server['bind_dn'], - password: server['password'], - name_proc: email_stripping_proc - end - end - - Gitlab.config.omniauth.providers.each do |provider| - provider_arguments = [] - - %w[app_id app_secret].each do |argument| - provider_arguments << provider[argument] if provider[argument] - end - - case provider['args'] - when Array - # An Array from the configuration will be expanded. - provider_arguments.concat provider['args'] - when Hash - # A Hash from the configuration will be passed as is. - provider_arguments << provider['args'] - end - - config.omniauth provider['name'].to_sym, *provider_arguments - end -end diff --git a/config/initializers/devise_async.rb b/config/initializers/devise_async.rb deleted file mode 100644 index 05a1852cdbd9d141a757755983adc59ad467f3ca..0000000000000000000000000000000000000000 --- a/config/initializers/devise_async.rb +++ /dev/null @@ -1 +0,0 @@ -Devise::Async.backend = :sidekiq diff --git a/config/initializers/devise_password_length.rb.example b/config/initializers/devise_password_length.rb.example deleted file mode 100644 index 97305825e07ccf9c7fd29e60c227168fd548ee64..0000000000000000000000000000000000000000 --- a/config/initializers/devise_password_length.rb.example +++ /dev/null @@ -1,6 +0,0 @@ -Devise.setup do |config| - # The following line changes the password length limits for new users. In the - # example below the minimum length is 12 characters, and the maximum length - # is 128 characters. - config.password_length = 12..128 -end diff --git a/config/initializers/disable_email_interceptor.rb b/config/initializers/disable_email_interceptor.rb deleted file mode 100644 index c76a6b8b19f51dbd1a6855eb171cc0b725e58863..0000000000000000000000000000000000000000 --- a/config/initializers/disable_email_interceptor.rb +++ /dev/null @@ -1,2 +0,0 @@ -# Interceptor in lib/disable_email_interceptor.rb -ActionMailer::Base.register_interceptor(DisableEmailInterceptor) unless Gitlab.config.gitlab.email_enabled diff --git a/config/initializers/gitlab_shell_secret_token.rb b/config/initializers/gitlab_shell_secret_token.rb deleted file mode 100644 index e7c9f0ba7c2b8025bcc520cc307c5e05edd3a01b..0000000000000000000000000000000000000000 --- a/config/initializers/gitlab_shell_secret_token.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Be sure to restart your server when you modify this file. - -require 'securerandom' - -# Your secret key for verifying the gitlab_shell. - - -secret_file = Rails.root.join('.gitlab_shell_secret') -gitlab_shell_symlink = File.join(Gitlab.config.gitlab_shell.path, '.gitlab_shell_secret') - -unless File.exist? secret_file - # Generate a new token of 16 random hexadecimal characters and store it in secret_file. - token = SecureRandom.hex(16) - File.write(secret_file, token) -end - -if File.exist?(Gitlab.config.gitlab_shell.path) && !File.exist?(gitlab_shell_symlink) - FileUtils.symlink(secret_file, gitlab_shell_symlink) -end diff --git a/config/initializers/haml.rb b/config/initializers/haml.rb deleted file mode 100644 index 7e8ddb3716bad55ceaa5fef99c9f2334c8afa07e..0000000000000000000000000000000000000000 --- a/config/initializers/haml.rb +++ /dev/null @@ -1 +0,0 @@ -Haml::Template.options[:ugly] = true diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb deleted file mode 100644 index 5d46ece1e1b27791215a48e141697abc40860dbb..0000000000000000000000000000000000000000 --- a/config/initializers/inflections.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format -# (all these examples are active by default): -# ActiveSupport::Inflector.inflections do |inflect| -# inflect.plural /^(ox)$/i, '\1en' -# inflect.singular /^(ox)en/i, '\1' -# inflect.irregular 'person', 'people' -# inflect.uncountable %w( fish sheep ) -# end - -# Mark "commits" as uncountable. -# -# Without this change, the routes -# -# resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/} -# resources :commits, only: [:show], constraints: {id: /.+/} -# -# would generate identical route helper methods (`project_commit_path`), resulting -# in one of them not getting a helper method at all. -# -# After this change, the helper methods are: -# -# project_commit_path(@project, @project.commit) -# # => "/gitlabhq/commit/bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a -# -# project_commits_path(@project, 'stable/README.md') -# # => "/gitlabhq/commits/stable/README.md" -ActiveSupport::Inflector.inflections do |inflect| - inflect.uncountable %w(commits) -end diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb deleted file mode 100644 index 3cbe9a058d7f0fc2480b692269335b4ee33ac6b2..0000000000000000000000000000000000000000 --- a/config/initializers/kaminari_config.rb +++ /dev/null @@ -1,10 +0,0 @@ -Kaminari.configure do |config| - config.default_per_page = 20 - config.max_per_page = 100 - # config.window = 4 - # config.outer_window = 0 - # config.left = 0 - # config.right = 0 - # config.page_method_name = :page - # config.param_name = :page -end diff --git a/config/initializers/postgresql_limit_fix.rb b/config/initializers/postgresql_limit_fix.rb deleted file mode 100644 index 0cb3aaf4d24c9b674d23cfa352850c3f7ff0ee1c..0000000000000000000000000000000000000000 --- a/config/initializers/postgresql_limit_fix.rb +++ /dev/null @@ -1,26 +0,0 @@ -if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) - class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter - class TableDefinition - def text(*args) - options = args.extract_options! - options.delete(:limit) - column_names = args - type = :text - column_names.each { |name| column(name, type, options) } - end - end - - def add_column_with_limit_filter(table_name, column_name, type, options = {}) - options.delete(:limit) if type == :text - add_column_without_limit_filter(table_name, column_name, type, options) - end - - def change_column_with_limit_filter(table_name, column_name, type, options = {}) - options.delete(:limit) if type == :text - change_column_without_limit_filter(table_name, column_name, type, options) - end - - alias_method_chain :add_column, :limit_filter - alias_method_chain :change_column, :limit_filter - end -end diff --git a/config/initializers/public_key.rb b/config/initializers/public_key.rb deleted file mode 100644 index e4f09a2d02058d36952d667b866e2ff603942d42..0000000000000000000000000000000000000000 --- a/config/initializers/public_key.rb +++ /dev/null @@ -1,2 +0,0 @@ -path = File.expand_path("~/.ssh/bitbucket_rsa.pub") -Gitlab::BitbucketImport.public_key = File.read(path) if File.exist?(path) diff --git a/config/initializers/rack_attack.rb.example b/config/initializers/rack_attack.rb.example deleted file mode 100644 index 332865d2881a0a3ad868356cbc4da107ba9ded3e..0000000000000000000000000000000000000000 --- a/config/initializers/rack_attack.rb.example +++ /dev/null @@ -1,26 +0,0 @@ -# 1. Rename this file to rack_attack.rb -# 2. Review the paths_to_be_protected and add any other path you need protecting -# - -paths_to_be_protected = [ - "#{Rails.application.config.relative_url_root}/users/password", - "#{Rails.application.config.relative_url_root}/users/sign_in", - "#{Rails.application.config.relative_url_root}/api/#{API::API.version}/session.json", - "#{Rails.application.config.relative_url_root}/api/#{API::API.version}/session", - "#{Rails.application.config.relative_url_root}/users", - "#{Rails.application.config.relative_url_root}/users/confirmation", - "#{Rails.application.config.relative_url_root}/unsubscribes/" - -] - -# Create one big regular expression that matches strings starting with any of -# the paths_to_be_protected. -paths_regex = Regexp.union(paths_to_be_protected.map { |path| /\A#{Regexp.escape(path)}/ }) - -unless Rails.env.test? - Rack::Attack.throttle('protected paths', limit: 10, period: 60.seconds) do |req| - if req.post? && req.path =~ paths_regex - req.ip - end - end -end diff --git a/config/initializers/rack_attack_git_basic_auth.rb b/config/initializers/rack_attack_git_basic_auth.rb deleted file mode 100644 index bbbfed6832923cb41e94d2defe0af74843bf77a4..0000000000000000000000000000000000000000 --- a/config/initializers/rack_attack_git_basic_auth.rb +++ /dev/null @@ -1,12 +0,0 @@ -unless Rails.env.test? - # Tell the Rack::Attack Rack middleware to maintain an IP blacklist. We will - # update the blacklist from Grack::Auth#authenticate_user. - Rack::Attack.blacklist('Git HTTP Basic Auth') do |req| - Rack::Attack::Allow2Ban.filter(req.ip, Gitlab.config.rack_attack.git_basic_auth) do - # This block only gets run if the IP was not already banned. - # Return false, meaning that we do not see anything wrong with the - # request at this time - false - end - end -end diff --git a/config/initializers/redis-store-fix-expiry.rb b/config/initializers/redis-store-fix-expiry.rb deleted file mode 100644 index fce0a13533012e92babfbb1dca780ad3b84932ff..0000000000000000000000000000000000000000 --- a/config/initializers/redis-store-fix-expiry.rb +++ /dev/null @@ -1,44 +0,0 @@ -# Monkey-patch Redis::Store to make 'setex' and 'expire' work with namespacing - -module Gitlab - class Redis - class Store - module Namespace - # Redis::Store#setex in redis-store 1.1.4 does not respect namespaces; - # this new method does. - def setex(key, expires_in, value, options=nil) - namespace(key) { |key| super(key, expires_in, value) } - end - - # Redis::Store#expire in redis-store 1.1.4 does not respect namespaces; - # this new method does. - def expire(key, expires_in) - namespace(key) { |key| super(key, expires_in) } - end - - private - - # Our new definitions of #setex and #expire above assume that the - # #namespace method exists. Because we cannot be sure of that, we - # re-implement the #namespace method from Redis::Store::Namespace so - # that it is available for all Redis::Store instances, whether they use - # namespacing or not. - # - # Based on lib/redis/store/namespace.rb L49-51 (redis-store 1.1.4) - def namespace(key) - if @namespace - yield interpolate(key) - else - # This Redis::Store instance does not use a namespace so we should - # just pass through the key. - yield key - end - end - end - end - end -end - -Redis::Store.class_eval do - include Gitlab::Redis::Store::Namespace -end diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb deleted file mode 100644 index 62a54bc8c63274b546eb70bdbafbfb6633cb682c..0000000000000000000000000000000000000000 --- a/config/initializers/secret_token.rb +++ /dev/null @@ -1,26 +0,0 @@ -# Be sure to restart your server when you modify this file. - -require 'securerandom' - -# Your secret key for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. - -def find_secure_token - token_file = Rails.root.join('.secret') - if ENV.key?('SECRET_KEY_BASE') - ENV['SECRET_KEY_BASE'] - elsif File.exist? token_file - # Use the existing token. - File.read(token_file).chomp - else - # Generate a new token of 64 random hexadecimal characters and store it in token_file. - token = SecureRandom.hex(64) - File.write(token_file, token) - token - end -end - -Gitlab::Application.config.secret_token = find_secure_token -Gitlab::Application.config.secret_key_base = find_secure_token diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb deleted file mode 100644 index b2d59f1c4b7e005f782d587476888953115c1bf3..0000000000000000000000000000000000000000 --- a/config/initializers/session_store.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Be sure to restart your server when you modify this file. - -Gitlab::Application.config.session_store( - :redis_store, # Using the cookie_store would enable session replay attacks. - servers: Gitlab::Application.config.cache_store[1].merge(namespace: 'session:gitlab'), # re-use the Redis config from the Rails cache store - key: '_gitlab_session', - secure: Gitlab.config.gitlab.https, - httponly: true, - expire_after: 1.week, - path: (Rails.application.config.relative_url_root.nil?) ? '/' : Rails.application.config.relative_url_root -) diff --git a/config/initializers/smtp_settings.rb.sample b/config/initializers/smtp_settings.rb.sample deleted file mode 100644 index f0fe2fdfa43909e794854815b4c9c51b92d83b04..0000000000000000000000000000000000000000 --- a/config/initializers/smtp_settings.rb.sample +++ /dev/null @@ -1,22 +0,0 @@ -# To enable smtp email delivery for your GitLab instance do the following: -# 1. Rename this file to smtp_settings.rb -# 2. Edit settings inside this file -# 3. Restart GitLab instance -# -# For full list of options and their values see http://api.rubyonrails.org/classes/ActionMailer/Base.html -# - -if Rails.env.production? - Gitlab::Application.config.action_mailer.delivery_method = :smtp - - ActionMailer::Base.smtp_settings = { - address: "email.server.com", - port: 456, - user_name: "smtp", - password: "123456", - domain: "gitlab.company.com", - authentication: :login, - enable_starttls_auto: true, - openssl_verify_mode: 'peer' # See ActionMailer documentation for other possible options - } -end diff --git a/config/initializers/state_machine_patch.rb b/config/initializers/state_machine_patch.rb deleted file mode 100644 index 72d010fa5deab3f48285ad4ab07f1793f6d9c3a2..0000000000000000000000000000000000000000 --- a/config/initializers/state_machine_patch.rb +++ /dev/null @@ -1,9 +0,0 @@ -# This is a patch to address the issue in https://github.com/pluginaweek/state_machine/issues/251 -# where gem 'state_machine' was not working for Rails 4.1 -module StateMachine - module Integrations - module ActiveModel - public :around_validation - end - end -end diff --git a/config/initializers/static_files.rb b/config/initializers/static_files.rb deleted file mode 100644 index d9042c652bb401fa3e1cd473392ca0160747c8c9..0000000000000000000000000000000000000000 --- a/config/initializers/static_files.rb +++ /dev/null @@ -1,15 +0,0 @@ -app = Rails.application - -if app.config.serve_static_assets - # The `ActionDispatch::Static` middleware intercepts requests for static files - # by checking if they exist in the `/public` directory. - # We're replacing it with our `Gitlab::Middleware::Static` that does the same, - # except ignoring `/uploads`, letting those go through to the GitLab Rails app. - - app.config.middleware.swap( - ActionDispatch::Static, - Gitlab::Middleware::Static, - app.paths["public"].first, - app.config.static_cache_control - ) -end diff --git a/config/initializers/time_zone.rb b/config/initializers/time_zone.rb deleted file mode 100644 index ee246e67d6687ea88fe0345a852a3902fa2a16bd..0000000000000000000000000000000000000000 --- a/config/initializers/time_zone.rb +++ /dev/null @@ -1 +0,0 @@ -Time.zone = Gitlab.config.gitlab.time_zone || Time.zone diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb deleted file mode 100644 index 999df20181e5571fb6a74259eead0899b7ad18a1..0000000000000000000000000000000000000000 --- a/config/initializers/wrap_parameters.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Be sure to restart your server when you modify this file. -# -# This file contains settings for ActionController::ParamsWrapper which -# is enabled by default. - -# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. -ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] -end - -# Disable root element in JSON by default. -ActiveSupport.on_load(:active_record) do - self.include_root_in_json = false -end diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml deleted file mode 100644 index f3db5b7476e1ab35221fe1e6cfd55d9be6c82492..0000000000000000000000000000000000000000 --- a/config/locales/devise.en.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Additional translations at http://github.com/plataformatec/devise/wiki/I18n - -en: - errors: - messages: - expired: "has expired, please request a new one" - not_found: "not found" - already_confirmed: "was already confirmed, please try signing in" - not_locked: "was not locked" - not_saved: - one: "1 error prohibited this %{resource} from being saved:" - other: "%{count} errors prohibited this %{resource} from being saved:" - - devise: - failure: - already_authenticated: 'You are already signed in.' - unauthenticated: 'You need to sign in before continuing.' - unconfirmed: 'You have to confirm your account before continuing.' - locked: 'Your account is locked.' - not_found_in_database: 'Invalid email or password.' - invalid: 'Invalid email or password.' - invalid_token: 'Invalid authentication token.' - timeout: 'Your session expired, please sign in again to continue.' - inactive: 'Your account was not activated yet.' - sessions: - signed_in: '' - signed_out: '' - users_sessions: - user: - signed_in: 'Signed in successfully.' - passwords: - send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.' - updated: 'Your password was changed successfully. You are now signed in.' - updated_not_active: 'Your password was changed successfully.' - send_paranoid_instructions: "If your e-mail exists on our database, you will receive a password recovery link on your e-mail" - confirmations: - send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.' - send_paranoid_instructions: 'If your e-mail exists on our database, you will receive an email with instructions about how to confirm your account in a few minutes.' - confirmed: 'Your account was successfully confirmed. You are now signed in.' - registrations: - signed_up: 'Welcome! You have signed up successfully.' - updated: 'You updated your account successfully.' - destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.' - signed_up_but_unconfirmed: 'A message with a confirmation link has been sent to your email address. Please open the link to activate your account.' - signed_up_but_inactive: 'You have signed up successfully. However, we could not sign you in because your account is not yet activated.' - signed_up_but_locked: 'You have signed up successfully. However, we could not sign you in because your account is locked.' - unlocks: - send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.' - unlocked: 'Your account was successfully unlocked. You are now signed in.' - send_paranoid_instructions: 'If your account exists, you will receive an email with instructions about how to unlock it in a few minutes.' - omniauth_callbacks: - success: 'Successfully authorized from %{kind} account.' - failure: 'Could not authorize you from %{kind} because "%{reason}".' - mailer: - confirmation_instructions: - subject: 'Confirmation instructions' - reset_password_instructions: - subject: 'Reset password instructions' - unlock_instructions: - subject: 'Unlock Instructions' \ No newline at end of file diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml deleted file mode 100644 index c5b6b75e7f6408f07c0b7cd387dfd0675f29341c..0000000000000000000000000000000000000000 --- a/config/locales/doorkeeper.en.yml +++ /dev/null @@ -1,73 +0,0 @@ -en: - activerecord: - errors: - models: - application: - attributes: - redirect_uri: - fragment_present: 'cannot contain a fragment.' - invalid_uri: 'must be a valid URI.' - relative_uri: 'must be an absolute URI.' - mongoid: - errors: - models: - application: - attributes: - redirect_uri: - fragment_present: 'cannot contain a fragment.' - invalid_uri: 'must be a valid URI.' - relative_uri: 'must be an absolute URI.' - mongo_mapper: - errors: - models: - application: - attributes: - redirect_uri: - fragment_present: 'cannot contain a fragment.' - invalid_uri: 'must be a valid URI.' - relative_uri: 'must be an absolute URI.' - doorkeeper: - errors: - messages: - # Common error messages - invalid_request: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.' - invalid_redirect_uri: 'The redirect uri included is not valid.' - unauthorized_client: 'The client is not authorized to perform this request using this method.' - access_denied: 'The resource owner or authorization server denied the request.' - invalid_scope: 'The requested scope is invalid, unknown, or malformed.' - server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.' - temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.' - - #configuration error messages - credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.' - resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.' - - # Access grant errors - unsupported_response_type: 'The authorization server does not support this response type.' - - # Access token errors - invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.' - invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.' - unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.' - - # Password Access token errors - invalid_resource_owner: 'The provided resource owner credentials are not valid, or resource owner cannot be found' - - invalid_token: - revoked: "The access token was revoked" - expired: "The access token expired" - unknown: "The access token is invalid" - scopes: - api: Access your API - - flash: - applications: - create: - notice: 'Application created.' - destroy: - notice: 'Application deleted.' - update: - notice: 'Application updated.' - authorized_applications: - destroy: - notice: 'Application revoked.' diff --git a/config/locales/en.yml b/config/locales/en.yml deleted file mode 100644 index f6cfb5efd2ada02443fe7939ad58f9b5922d719e..0000000000000000000000000000000000000000 --- a/config/locales/en.yml +++ /dev/null @@ -1,10 +0,0 @@ -# Sample localization file for English. Add more files in this directory for other locales. -# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. - -en: - hello: "Hello world" - errors: - messages: - wrong_size: "is the wrong size (should be %{file_size})" - size_too_small: "is too small (should be at least %{file_size})" - size_too_big: "is too big (should be at most %{file_size})" diff --git a/config/newrelic.yml b/config/newrelic.yml deleted file mode 100644 index 9ef922a38d9c969e4a98b551e31a785f32d25d7b..0000000000000000000000000000000000000000 --- a/config/newrelic.yml +++ /dev/null @@ -1,16 +0,0 @@ -# New Relic configuration file -# -# This file is here to make sure the New Relic gem stays -# quiet by default. -# -# To enable and configure New Relic, please use -# environment variables, e.g. NEW_RELIC_ENABLED=true - -production: - enabled: false - -development: - enabled: false - -test: - enabled: false diff --git a/config/resque.yml.example b/config/resque.yml.example deleted file mode 100644 index 347f3599b206927a82efac6118507d4635373425..0000000000000000000000000000000000000000 --- a/config/resque.yml.example +++ /dev/null @@ -1,3 +0,0 @@ -development: redis://localhost:6379 -test: redis://localhost:6379 -production: unix:/var/run/redis/redis.sock diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example deleted file mode 100644 index 86a5512e761982b0cfa80edf6ed5a793dece593d..0000000000000000000000000000000000000000 --- a/config/unicorn.rb.example +++ /dev/null @@ -1,123 +0,0 @@ -# Sample verbose configuration file for Unicorn (not Rack) -# -# This configuration file documents many features of Unicorn -# that may not be needed for some applications. See -# http://unicorn.bogomips.org/examples/unicorn.conf.minimal.rb -# for a much simpler configuration file. -# -# See http://unicorn.bogomips.org/Unicorn/Configurator.html for complete -# documentation. - -# WARNING: See config/application.rb under "Relative url support" for the list of -# other files that need to be changed for relative url support -# -# ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab" - -# Read about unicorn workers here: -# http://doc.gitlab.com/ee/install/requirements.html#unicorn-workers -# -worker_processes 3 - -# Since Unicorn is never exposed to outside clients, it does not need to -# run on the standard HTTP port (80), there is no reason to start Unicorn -# as root unless it's from system init scripts. -# If running the master process as root and the workers as an unprivileged -# user, do this to switch euid/egid in the workers (also chowns logs): -# user "unprivileged_user", "unprivileged_group" - -# Help ensure your application will always spawn in the symlinked -# "current" directory that Capistrano sets up. -working_directory "/home/git/gitlab" # available in 0.94.0+ - -# Listen on both a Unix domain socket and a TCP port. -# If you are load-balancing multiple Unicorn masters, lower the backlog -# setting to e.g. 64 for faster failover. -listen "/home/git/gitlab/tmp/sockets/gitlab.socket", :backlog => 1024 -listen "127.0.0.1:8080", :tcp_nopush => true - -# nuke workers after 30 seconds instead of 60 seconds (the default) -# -# NOTICE: git push over http depends on this value. -# If you want be able to push huge amount of data to git repository over http -# you will have to increase this value too. -# -# Example of output if you try to push 1GB repo to GitLab over http. -# -> git push http://gitlab.... master -# -# error: RPC failed; result=18, HTTP code = 200 -# fatal: The remote end hung up unexpectedly -# fatal: The remote end hung up unexpectedly -# -# For more information see http://stackoverflow.com/a/21682112/752049 -# -timeout 60 - -# feel free to point this anywhere accessible on the filesystem -pid "/home/git/gitlab/tmp/pids/unicorn.pid" - -# By default, the Unicorn logger will write to stderr. -# Additionally, some applications/frameworks log to stderr or stdout, -# so prevent them from going to /dev/null when daemonized here: -stderr_path "/home/git/gitlab/log/unicorn.stderr.log" -stdout_path "/home/git/gitlab/log/unicorn.stdout.log" - -# combine Ruby 2.0.0dev or REE with "preload_app true" for memory savings -# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow -preload_app true -GC.respond_to?(:copy_on_write_friendly=) and - GC.copy_on_write_friendly = true - -# Enable this flag to have unicorn test client connections by writing the -# beginning of the HTTP headers before calling the application. This -# prevents calling the application for connections that have disconnected -# while queued. This is only guaranteed to detect clients on the same -# host unicorn runs on, and unlikely to detect disconnects even on a -# fast LAN. -check_client_connection false - -before_fork do |server, worker| - # the following is highly recomended for Rails + "preload_app true" - # as there's no need for the master process to hold a connection - defined?(ActiveRecord::Base) and - ActiveRecord::Base.connection.disconnect! - - # The following is only recommended for memory/DB-constrained - # installations. It is not needed if your system can house - # twice as many worker_processes as you have configured. - # - # This allows a new master process to incrementally - # phase out the old master process with SIGTTOU to avoid a - # thundering herd (especially in the "preload_app false" case) - # when doing a transparent upgrade. The last worker spawned - # will then kill off the old master process with a SIGQUIT. - old_pid = "#{server.config[:pid]}.oldbin" - if old_pid != server.pid - begin - sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU - Process.kill(sig, File.read(old_pid).to_i) - rescue Errno::ENOENT, Errno::ESRCH - end - end - # - # Throttle the master from forking too quickly by sleeping. Due - # to the implementation of standard Unix signal handlers, this - # helps (but does not completely) prevent identical, repeated signals - # from being lost when the receiving process is busy. - # sleep 1 -end - -after_fork do |server, worker| - # per-process listener ports for debugging/admin/migrations - # addr = "127.0.0.1:#{9293 + worker.nr}" - # server.listen(addr, :tries => -1, :delay => 5, :tcp_nopush => true) - - # the following is *required* for Rails + "preload_app true", - defined?(ActiveRecord::Base) and - ActiveRecord::Base.establish_connection - - # if preload_app is true, then you may also want to check and - # restart any other shared sockets/descriptors such as Memcached, - # and Redis. TokyoCabinet file handles are safe to reuse - # between any number of forked children (assuming your kernel - # correctly implements pread()/pwrite() system calls) -end diff --git a/config/unicorn.rb.example.development b/config/unicorn.rb.example.development deleted file mode 100644 index 3cd00d53a151e35a8711378c657b66764b8be1ca..0000000000000000000000000000000000000000 --- a/config/unicorn.rb.example.development +++ /dev/null @@ -1,2 +0,0 @@ -worker_processes 2 -timeout 60 diff --git a/db/fixtures/development/01_admin.rb b/db/fixtures/development/01_admin.rb deleted file mode 100644 index bba2fc4b186ea050f64b106928d22db3011d38ef..0000000000000000000000000000000000000000 --- a/db/fixtures/development/01_admin.rb +++ /dev/null @@ -1,13 +0,0 @@ -Gitlab::Seeder.quiet do - User.seed do |s| - s.id = 1 - s.name = 'Administrator' - s.email = 'admin@example.com' - s.notification_email = 'admin@example.com' - s.username = 'root' - s.password = '5iveL!fe' - s.admin = true - s.projects_limit = 100 - s.confirmed_at = DateTime.now - end -end diff --git a/db/fixtures/development/04_project.rb b/db/fixtures/development/04_project.rb deleted file mode 100644 index ae4c0550a4f8fcfc4d022b5d9fcb1248417295e3..0000000000000000000000000000000000000000 --- a/db/fixtures/development/04_project.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'sidekiq/testing' - -Sidekiq::Testing.inline! do - Gitlab::Seeder.quiet do - project_urls = [ - 'https://github.com/documentcloud/underscore.git', - 'https://gitlab.com/gitlab-org/gitlab-ce.git', - 'https://gitlab.com/gitlab-org/gitlab-ci.git', - 'https://gitlab.com/gitlab-org/gitlab-shell.git', - 'https://gitlab.com/gitlab-org/gitlab-test.git', - 'https://github.com/twitter/flight.git', - 'https://github.com/twitter/typeahead.js.git', - 'https://github.com/h5bp/html5-boilerplate.git', - ] - - project_urls.each_with_index do |url, i| - group_path, project_path = url.split('/')[-2..-1] - - group = Group.find_by(path: group_path) - - unless group - group = Group.new( - name: group_path.titleize, - path: group_path - ) - group.description = Faker::Lorem.sentence - group.save - - group.add_owner(User.first) - end - - project_path.gsub!(".git", "") - - params = { - import_url: url, - namespace_id: group.id, - name: project_path.titleize, - description: Faker::Lorem.sentence, - visibility_level: Gitlab::VisibilityLevel.values.sample - } - - project = Projects::CreateService.new(User.first, params).execute - - if project.valid? - print '.' - else - puts project.errors.full_messages - print 'F' - end - end - end -end diff --git a/db/fixtures/development/05_users.rb b/db/fixtures/development/05_users.rb deleted file mode 100644 index 24952a1f66167a2d324380de6791c34b9399535f..0000000000000000000000000000000000000000 --- a/db/fixtures/development/05_users.rb +++ /dev/null @@ -1,32 +0,0 @@ -Gitlab::Seeder.quiet do - (2..20).each do |i| - begin - User.create!( - username: Faker::Internet.user_name, - name: Faker::Name.name, - email: Faker::Internet.email, - confirmed_at: DateTime.now, - password: '12345678' - ) - - print '.' - rescue ActiveRecord::RecordInvalid - print 'F' - end - end - - (1..5).each do |i| - begin - User.create!( - username: "user#{i}", - name: "User #{i}", - email: "user#{i}@example.com", - confirmed_at: DateTime.now, - password: '12345678' - ) - print '.' - rescue ActiveRecord::RecordInvalid - print 'F' - end - end -end diff --git a/db/fixtures/development/06_teams.rb b/db/fixtures/development/06_teams.rb deleted file mode 100644 index 3e8cdcd67b4a66ab88eb6927453d98782b85bfa2..0000000000000000000000000000000000000000 --- a/db/fixtures/development/06_teams.rb +++ /dev/null @@ -1,21 +0,0 @@ -Gitlab::Seeder.quiet do - Group.all.each do |group| - User.all.sample(4).each do |user| - if group.add_users([user.id], Gitlab::Access.values.sample) - print '.' - else - print 'F' - end - end - end - - Project.all.each do |project| - User.all.sample(4).each do |user| - if project.team << [user, Gitlab::Access.values.sample] - print '.' - else - print 'F' - end - end - end -end diff --git a/db/fixtures/development/07_milestones.rb b/db/fixtures/development/07_milestones.rb deleted file mode 100644 index 2296821e528b7d2f3672e9ecaebfcc66589cc838..0000000000000000000000000000000000000000 --- a/db/fixtures/development/07_milestones.rb +++ /dev/null @@ -1,16 +0,0 @@ -Gitlab::Seeder.quiet do - Project.all.each do |project| - (1..5).each do |i| - milestone_params = { - title: "v#{i}.0", - description: Faker::Lorem.sentence, - state: ['opened', 'closed'].sample, - } - - milestone = Milestones::CreateService.new( - project, project.team.users.sample, milestone_params).execute - - print '.' - end - end -end diff --git a/db/fixtures/development/09_issues.rb b/db/fixtures/development/09_issues.rb deleted file mode 100644 index e8b01b46d22138dd9a75b1d07f22a151dd1b5840..0000000000000000000000000000000000000000 --- a/db/fixtures/development/09_issues.rb +++ /dev/null @@ -1,16 +0,0 @@ -Gitlab::Seeder.quiet do - Project.all.each do |project| - (1..10).each do |i| - issue_params = { - title: Faker::Lorem.sentence(6), - description: Faker::Lorem.sentence, - state: ['opened', 'closed'].sample, - milestone: project.milestones.sample, - assignee: project.team.users.sample - } - - Issues::CreateService.new(project, project.team.users.sample, issue_params).execute - print '.' - end - end -end diff --git a/db/fixtures/development/10_merge_requests.rb b/db/fixtures/development/10_merge_requests.rb deleted file mode 100644 index f9b2fd8b05fd044e95bcb381b258562206132821..0000000000000000000000000000000000000000 --- a/db/fixtures/development/10_merge_requests.rb +++ /dev/null @@ -1,41 +0,0 @@ -Gitlab::Seeder.quiet do - Project.all.reject(&:empty_repo?).each do |project| - branches = project.repository.branch_names - - branches.each do |branch_name| - break if branches.size < 2 - source_branch = branches.pop - target_branch = branches.pop - - params = { - source_branch: source_branch, - target_branch: target_branch, - title: Faker::Lorem.sentence(6), - description: Faker::Lorem.sentences(3).join(" "), - milestone: project.milestones.sample, - assignee: project.team.users.sample - } - - MergeRequests::CreateService.new(project, project.team.users.sample, params).execute - print '.' - end - end - - project = Project.find_with_namespace('gitlab-org/gitlab-test') - - params = { - source_branch: 'feature', - target_branch: 'master', - title: 'Can be automatically merged' - } - MergeRequests::CreateService.new(project, User.admins.first, params).execute - print '.' - - params = { - source_branch: 'feature_conflict', - target_branch: 'feature', - title: 'Cannot be automatically merged' - } - MergeRequests::CreateService.new(project, User.admins.first, params).execute - print '.' -end diff --git a/db/fixtures/development/11_keys.rb b/db/fixtures/development/11_keys.rb deleted file mode 100644 index 8b4bee384e1551dda3e98511ecb0a48612a71b25..0000000000000000000000000000000000000000 --- a/db/fixtures/development/11_keys.rb +++ /dev/null @@ -1,12 +0,0 @@ -Gitlab::Seeder.quiet do - User.first(10).each do |user| - key = "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt#{user.id + 100}6k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" - - user.keys.create( - title: "Sample key #{user.id}", - key: key - ) - - print '.' - end -end diff --git a/db/fixtures/development/12_snippets.rb b/db/fixtures/development/12_snippets.rb deleted file mode 100644 index b3a6f39c7d5d0e1890629bca0243ded24d64f02c..0000000000000000000000000000000000000000 --- a/db/fixtures/development/12_snippets.rb +++ /dev/null @@ -1,40 +0,0 @@ -Gitlab::Seeder.quiet do - content =< { where(access_level: GUEST) } - scope :reporters, -> { where(access_level: REPORTER) } - scope :developers, -> { where(access_level: DEVELOPER) } - scope :masters, -> { where(access_level: MASTER) } - scope :owners, -> { where(access_level: OWNER) } - - delegate :name, :username, :email, to: :user, prefix: true -end -eos - - (1..50).each do |i| - user = User.all.sample - - PersonalSnippet.seed(:id, [{ - id: i, - author_id: user.id, - title: Faker::Lorem.sentence(3), - file_name: Faker::Internet.domain_word + '.rb', - visibility_level: Gitlab::VisibilityLevel.values.sample, - content: content, - }]) - - print('.') - end -end - diff --git a/db/fixtures/development/13_comments.rb b/db/fixtures/development/13_comments.rb deleted file mode 100644 index d37be53c7b93e657953e48b4dac0a3611d9bd1ab..0000000000000000000000000000000000000000 --- a/db/fixtures/development/13_comments.rb +++ /dev/null @@ -1,31 +0,0 @@ -Gitlab::Seeder.quiet do - Issue.all.each do |issue| - project = issue.project - - project.team.users.each do |user| - note_params = { - noteable_type: 'Issue', - noteable_id: issue.id, - note: Faker::Lorem.sentence, - } - - Notes::CreateService.new(project, user, note_params).execute - print '.' - end - end - - MergeRequest.all.each do |mr| - project = mr.project - - project.team.users.each do |user| - note_params = { - noteable_type: 'MergeRequest', - noteable_id: mr.id, - note: Faker::Lorem.sentence, - } - - Notes::CreateService.new(project, user, note_params).execute - print '.' - end - end -end diff --git a/db/fixtures/production/001_admin.rb b/db/fixtures/production/001_admin.rb deleted file mode 100644 index 8b560ee09e00251a28c05b13d9d972f0a0c23946..0000000000000000000000000000000000000000 --- a/db/fixtures/production/001_admin.rb +++ /dev/null @@ -1,31 +0,0 @@ -if ENV['GITLAB_ROOT_PASSWORD'].blank? - password = '5iveL!fe' - expire_time = Time.now -else - password = ENV['GITLAB_ROOT_PASSWORD'] - expire_time = nil -end - -admin = User.create( - email: "admin@example.com", - name: "Administrator", - username: 'root', - password: password, - password_expires_at: expire_time, - theme_id: Gitlab::Theme::MARS - -) - -admin.projects_limit = 10000 -admin.admin = true -admin.save! -admin.confirm! - -if admin.valid? -puts %Q[ -Administrator account created: - -login.........root -password......#{password} -] -end diff --git a/db/fixtures/test/001_repo.rb b/db/fixtures/test/001_repo.rb deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/db/migrate/20121220064453_init_schema.rb b/db/migrate/20121220064453_init_schema.rb deleted file mode 100644 index 90f5eb08e8cdaf539a99f3c469e27977c6ae1908..0000000000000000000000000000000000000000 --- a/db/migrate/20121220064453_init_schema.rb +++ /dev/null @@ -1,306 +0,0 @@ -class InitSchema < ActiveRecord::Migration - def up - - create_table "events", force: true do |t| - t.string "target_type" - t.integer "target_id" - t.string "title" - t.text "data" - t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "action" - t.integer "author_id" - end - - add_index "events", ["action"], name: "index_events_on_action", using: :btree - add_index "events", ["author_id"], name: "index_events_on_author_id", using: :btree - add_index "events", ["created_at"], name: "index_events_on_created_at", using: :btree - add_index "events", ["project_id"], name: "index_events_on_project_id", using: :btree - add_index "events", ["target_id"], name: "index_events_on_target_id", using: :btree - add_index "events", ["target_type"], name: "index_events_on_target_type", using: :btree - - create_table "issues", force: true do |t| - t.string "title" - t.integer "assignee_id" - t.integer "author_id" - t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "closed", default: false, null: false - t.integer "position", default: 0 - t.string "branch_name" - t.text "description" - t.integer "milestone_id" - end - - add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree - add_index "issues", ["author_id"], name: "index_issues_on_author_id", using: :btree - add_index "issues", ["closed"], name: "index_issues_on_closed", using: :btree - add_index "issues", ["created_at"], name: "index_issues_on_created_at", using: :btree - add_index "issues", ["milestone_id"], name: "index_issues_on_milestone_id", using: :btree - add_index "issues", ["project_id"], name: "index_issues_on_project_id", using: :btree - add_index "issues", ["title"], name: "index_issues_on_title", using: :btree - - create_table "keys", force: true do |t| - t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" - t.text "key" - t.string "title" - t.string "identifier" - t.integer "project_id" - end - - add_index "keys", ["identifier"], name: "index_keys_on_identifier", using: :btree - add_index "keys", ["project_id"], name: "index_keys_on_project_id", using: :btree - add_index "keys", ["user_id"], name: "index_keys_on_user_id", using: :btree - - create_table "merge_requests", force: true do |t| - t.string "target_branch", null: false - t.string "source_branch", null: false - t.integer "project_id", null: false - t.integer "author_id" - t.integer "assignee_id" - t.string "title" - t.boolean "closed", default: false, null: false - t.datetime "created_at" - t.datetime "updated_at" - t.text "st_commits", limit: 2147483647 - t.text "st_diffs", limit: 2147483647 - t.boolean "merged", default: false, null: false - t.integer "state", default: 1, null: false - t.integer "milestone_id" - end - - add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree - add_index "merge_requests", ["author_id"], name: "index_merge_requests_on_author_id", using: :btree - add_index "merge_requests", ["closed"], name: "index_merge_requests_on_closed", using: :btree - add_index "merge_requests", ["created_at"], name: "index_merge_requests_on_created_at", using: :btree - add_index "merge_requests", ["milestone_id"], name: "index_merge_requests_on_milestone_id", using: :btree - add_index "merge_requests", ["project_id"], name: "index_merge_requests_on_project_id", using: :btree - add_index "merge_requests", ["source_branch"], name: "index_merge_requests_on_source_branch", using: :btree - add_index "merge_requests", ["target_branch"], name: "index_merge_requests_on_target_branch", using: :btree - add_index "merge_requests", ["title"], name: "index_merge_requests_on_title", using: :btree - - create_table "milestones", force: true do |t| - t.string "title", null: false - t.integer "project_id", null: false - t.text "description" - t.date "due_date" - t.boolean "closed", default: false, null: false - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "milestones", ["due_date"], name: "index_milestones_on_due_date", using: :btree - add_index "milestones", ["project_id"], name: "index_milestones_on_project_id", using: :btree - - create_table "namespaces", force: true do |t| - t.string "name", null: false - t.string "path", null: false - t.integer "owner_id", null: false - t.datetime "created_at" - t.datetime "updated_at" - t.string "type" - end - - add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree - add_index "namespaces", ["owner_id"], name: "index_namespaces_on_owner_id", using: :btree - add_index "namespaces", ["path"], name: "index_namespaces_on_path", using: :btree - add_index "namespaces", ["type"], name: "index_namespaces_on_type", using: :btree - - create_table "notes", force: true do |t| - t.text "note" - t.string "noteable_type" - t.integer "author_id" - t.datetime "created_at" - t.datetime "updated_at" - t.integer "project_id" - t.string "attachment" - t.string "line_code" - t.string "commit_id" - t.integer "noteable_id" - end - - add_index "notes", ["commit_id"], name: "index_notes_on_commit_id", using: :btree - add_index "notes", ["created_at"], name: "index_notes_on_created_at", using: :btree - add_index "notes", ["noteable_type"], name: "index_notes_on_noteable_type", using: :btree - add_index "notes", ["project_id", "noteable_type"], name: "index_notes_on_project_id_and_noteable_type", using: :btree - add_index "notes", ["project_id"], name: "index_notes_on_project_id", using: :btree - - create_table "projects", force: true do |t| - t.string "name" - t.string "path" - t.text "description" - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "private_flag", default: true, null: false - t.integer "owner_id" - t.string "default_branch" - t.boolean "issues_enabled", default: true, null: false - t.boolean "wall_enabled", default: true, null: false - t.boolean "merge_requests_enabled", default: true, null: false - t.boolean "wiki_enabled", default: true, null: false - t.integer "namespace_id" - end - - add_index "projects", ["namespace_id"], name: "index_projects_on_namespace_id", using: :btree - add_index "projects", ["owner_id"], name: "index_projects_on_owner_id", using: :btree - - create_table "protected_branches", force: true do |t| - t.integer "project_id", null: false - t.string "name", null: false - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "services", force: true do |t| - t.string "type" - t.string "title" - t.string "token" - t.integer "project_id", null: false - t.datetime "created_at" - t.datetime "updated_at" - t.boolean "active", default: false, null: false - t.string "project_url" - end - - add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree - - create_table "snippets", force: true do |t| - t.string "title" - t.text "content" - t.integer "author_id", null: false - t.integer "project_id", null: false - t.datetime "created_at" - t.datetime "updated_at" - t.string "file_name" - t.datetime "expires_at" - end - - add_index "snippets", ["created_at"], name: "index_snippets_on_created_at", using: :btree - add_index "snippets", ["expires_at"], name: "index_snippets_on_expires_at", using: :btree - add_index "snippets", ["project_id"], name: "index_snippets_on_project_id", using: :btree - - create_table "taggings", force: true do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context" - t.datetime "created_at" - end - - add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id", using: :btree - add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree - - create_table "tags", force: true do |t| - t.string "name" - end - - create_table "user_team_project_relationships", force: true do |t| - t.integer "project_id" - t.integer "user_team_id" - t.integer "greatest_access" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "user_team_user_relationships", force: true do |t| - t.integer "user_id" - t.integer "user_team_id" - t.boolean "group_admin" - t.integer "permission" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "user_teams", force: true do |t| - t.string "name" - t.string "path" - t.integer "owner_id" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "users", force: true do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" - t.datetime "created_at" - t.datetime "updated_at" - t.string "name" - t.boolean "admin", default: false, null: false - t.integer "projects_limit", default: 10 - t.string "skype", default: "", null: false - t.string "linkedin", default: "", null: false - t.string "twitter", default: "", null: false - t.string "authentication_token" - t.boolean "dark_scheme", default: false, null: false - t.integer "theme_id", default: 1, null: false - t.string "bio" - t.boolean "blocked", default: false, null: false - t.integer "failed_attempts", default: 0 - t.datetime "locked_at" - t.string "extern_uid" - t.string "provider" - t.string "username" - end - - add_index "users", ["admin"], name: "index_users_on_admin", using: :btree - add_index "users", ["blocked"], name: "index_users_on_blocked", using: :btree - add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree - add_index "users", ["extern_uid", "provider"], name: "index_users_on_extern_uid_and_provider", unique: true, using: :btree - add_index "users", ["name"], name: "index_users_on_name", using: :btree - add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree - add_index "users", ["username"], name: "index_users_on_username", using: :btree - - create_table "users_projects", force: true do |t| - t.integer "user_id", null: false - t.integer "project_id", null: false - t.datetime "created_at" - t.datetime "updated_at" - t.integer "project_access", default: 0, null: false - end - - add_index "users_projects", ["project_access"], name: "index_users_projects_on_project_access", using: :btree - add_index "users_projects", ["project_id"], name: "index_users_projects_on_project_id", using: :btree - add_index "users_projects", ["user_id"], name: "index_users_projects_on_user_id", using: :btree - - create_table "web_hooks", force: true do |t| - t.string "url" - t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" - t.string "type", default: "ProjectHook" - t.integer "service_id" - end - - create_table "wikis", force: true do |t| - t.string "title" - t.text "content" - t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" - t.string "slug" - t.integer "user_id" - end - - add_index "wikis", ["project_id"], name: "index_wikis_on_project_id", using: :btree - add_index "wikis", ["slug"], name: "index_wikis_on_slug", using: :btree - - end - - def down - raise "Can not revert initial migration" - end -end diff --git a/db/migrate/20130102143055_rename_owner_to_creator_for_project.rb b/db/migrate/20130102143055_rename_owner_to_creator_for_project.rb deleted file mode 100644 index d0fca269871dcfb475905d12fadaafca359e3614..0000000000000000000000000000000000000000 --- a/db/migrate/20130102143055_rename_owner_to_creator_for_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenameOwnerToCreatorForProject < ActiveRecord::Migration - def change - rename_column :projects, :owner_id, :creator_id - end -end diff --git a/db/migrate/20130110172407_add_public_to_project.rb b/db/migrate/20130110172407_add_public_to_project.rb deleted file mode 100644 index 45edba48152aabbd93949b25da9cd50d82f55569..0000000000000000000000000000000000000000 --- a/db/migrate/20130110172407_add_public_to_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPublicToProject < ActiveRecord::Migration - def change - add_column :projects, :public, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20130123114545_add_issues_tracker_to_project.rb b/db/migrate/20130123114545_add_issues_tracker_to_project.rb deleted file mode 100644 index 288d0f07c9ae58c6d973cf128dd4241edc6071ff..0000000000000000000000000000000000000000 --- a/db/migrate/20130123114545_add_issues_tracker_to_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIssuesTrackerToProject < ActiveRecord::Migration - def change - add_column :projects, :issues_tracker, :string, default: :gitlab, null: false - end -end diff --git a/db/migrate/20130125090214_add_user_permissions.rb b/db/migrate/20130125090214_add_user_permissions.rb deleted file mode 100644 index 38b5f439a2d22687348aacc87ad919c51440ca6f..0000000000000000000000000000000000000000 --- a/db/migrate/20130125090214_add_user_permissions.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddUserPermissions < ActiveRecord::Migration - def up - add_column :users, :can_create_group, :boolean, default: true, null: false - add_column :users, :can_create_team, :boolean, default: true, null: false - end - - def down - remove_column :users, :can_create_group - remove_column :users, :can_create_team - end -end diff --git a/db/migrate/20130131070232_remove_private_flag_from_project.rb b/db/migrate/20130131070232_remove_private_flag_from_project.rb deleted file mode 100644 index 5754db115589d6442a1c5a1bc9991b68c2b8937c..0000000000000000000000000000000000000000 --- a/db/migrate/20130131070232_remove_private_flag_from_project.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemovePrivateFlagFromProject < ActiveRecord::Migration - def up - remove_column :projects, :private_flag - end - - def down - add_column :projects, :private_flag, :boolean, default: true, null: false - end -end diff --git a/db/migrate/20130206084024_add_description_to_namsespace.rb b/db/migrate/20130206084024_add_description_to_namsespace.rb deleted file mode 100644 index ef02e489d03088e33a910f487d8a6677f90575c8..0000000000000000000000000000000000000000 --- a/db/migrate/20130206084024_add_description_to_namsespace.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDescriptionToNamsespace < ActiveRecord::Migration - def change - add_column :namespaces, :description, :string, default: '', null: false - end -end diff --git a/db/migrate/20130207104426_add_description_to_teams.rb b/db/migrate/20130207104426_add_description_to_teams.rb deleted file mode 100644 index 6d03777901c44333ba34990af2ecef9a62977813..0000000000000000000000000000000000000000 --- a/db/migrate/20130207104426_add_description_to_teams.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDescriptionToTeams < ActiveRecord::Migration - def change - add_column :user_teams, :description, :string, default: '', null: false - end -end diff --git a/db/migrate/20130211085435_add_issues_tracker_id_to_project.rb b/db/migrate/20130211085435_add_issues_tracker_id_to_project.rb deleted file mode 100644 index 71763d18aee5be037148417d05d72016dbd6c4ae..0000000000000000000000000000000000000000 --- a/db/migrate/20130211085435_add_issues_tracker_id_to_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIssuesTrackerIdToProject < ActiveRecord::Migration - def change - add_column :projects, :issues_tracker_id, :string - end -end diff --git a/db/migrate/20130214154045_rename_state_to_merge_status_in_milestone.rb b/db/migrate/20130214154045_rename_state_to_merge_status_in_milestone.rb deleted file mode 100644 index 23797fe1894750acf664bb81c5be985b0071204f..0000000000000000000000000000000000000000 --- a/db/migrate/20130214154045_rename_state_to_merge_status_in_milestone.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenameStateToMergeStatusInMilestone < ActiveRecord::Migration - def change - rename_column :merge_requests, :state, :merge_status - end -end diff --git a/db/migrate/20130218140952_add_state_to_issue.rb b/db/migrate/20130218140952_add_state_to_issue.rb deleted file mode 100644 index 062103d0e3389f948b3539bbfc79d6ad820b4351..0000000000000000000000000000000000000000 --- a/db/migrate/20130218140952_add_state_to_issue.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddStateToIssue < ActiveRecord::Migration - def change - add_column :issues, :state, :string - end -end diff --git a/db/migrate/20130218141038_add_state_to_merge_request.rb b/db/migrate/20130218141038_add_state_to_merge_request.rb deleted file mode 100644 index ac4108ee311b5ef0854f2ee81ba1c026a0af8b38..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141038_add_state_to_merge_request.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddStateToMergeRequest < ActiveRecord::Migration - def change - add_column :merge_requests, :state, :string - end -end diff --git a/db/migrate/20130218141117_add_state_to_milestone.rb b/db/migrate/20130218141117_add_state_to_milestone.rb deleted file mode 100644 index c84039106bd9064a3825a65d21fbec38e248eed7..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141117_add_state_to_milestone.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddStateToMilestone < ActiveRecord::Migration - def change - add_column :milestones, :state, :string - end -end diff --git a/db/migrate/20130218141258_convert_closed_to_state_in_issue.rb b/db/migrate/20130218141258_convert_closed_to_state_in_issue.rb deleted file mode 100644 index 9fa96203ffdd96f34e592e4897ae5c6845e08cb3..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141258_convert_closed_to_state_in_issue.rb +++ /dev/null @@ -1,14 +0,0 @@ -class ConvertClosedToStateInIssue < ActiveRecord::Migration - def up - Issue.transaction do - Issue.where(closed: true).update_all(state: :closed) - Issue.where(closed: false).update_all(state: :opened) - end - end - - def down - Issue.transaction do - Issue.where(state: :closed).update_all(closed: true) - end - end -end diff --git a/db/migrate/20130218141327_convert_closed_to_state_in_merge_request.rb b/db/migrate/20130218141327_convert_closed_to_state_in_merge_request.rb deleted file mode 100644 index ebb7ae585e68b8cc26bf14dc473a74ac2c33ecfc..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141327_convert_closed_to_state_in_merge_request.rb +++ /dev/null @@ -1,16 +0,0 @@ -class ConvertClosedToStateInMergeRequest < ActiveRecord::Migration - def up - MergeRequest.transaction do - MergeRequest.where(closed: true, merged: true).update_all(state: :merged) - MergeRequest.where(closed: true, merged: false).update_all(state: :closed) - MergeRequest.where(closed: false).update_all(state: :opened) - end - end - - def down - MergeRequest.transaction do - MergeRequest.where(state: :closed).update_all(closed: true) - MergeRequest.where(state: :merged).update_all(closed: true, merged: true) - end - end -end diff --git a/db/migrate/20130218141344_convert_closed_to_state_in_milestone.rb b/db/migrate/20130218141344_convert_closed_to_state_in_milestone.rb deleted file mode 100644 index 1978ea8915390ac6a76e6ccdc49d143e2ce53a7e..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141344_convert_closed_to_state_in_milestone.rb +++ /dev/null @@ -1,14 +0,0 @@ -class ConvertClosedToStateInMilestone < ActiveRecord::Migration - def up - Milestone.transaction do - Milestone.where(closed: true).update_all(state: :closed) - Milestone.where(closed: false).update_all(state: :active) - end - end - - def down - Milestone.transaction do - Milestone.where(state: :closed).update_all(closed: true) - end - end -end diff --git a/db/migrate/20130218141444_remove_merged_from_merge_request.rb b/db/migrate/20130218141444_remove_merged_from_merge_request.rb deleted file mode 100644 index a7bd82f500096e2d0a54080ff225cf636ff56532..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141444_remove_merged_from_merge_request.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveMergedFromMergeRequest < ActiveRecord::Migration - def up - remove_column :merge_requests, :merged - end - - def down - add_column :merge_requests, :merged, :boolean, default: true, null: false - end -end diff --git a/db/migrate/20130218141507_remove_closed_from_issue.rb b/db/migrate/20130218141507_remove_closed_from_issue.rb deleted file mode 100644 index 95cc064252b8f603b5e7bcb9365ae74ea82600c0..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141507_remove_closed_from_issue.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveClosedFromIssue < ActiveRecord::Migration - def up - remove_column :issues, :closed - end - - def down - add_column :issues, :closed, :boolean - end -end diff --git a/db/migrate/20130218141536_remove_closed_from_merge_request.rb b/db/migrate/20130218141536_remove_closed_from_merge_request.rb deleted file mode 100644 index 371835938b213308efc9ef18bba15b1958fb4e66..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141536_remove_closed_from_merge_request.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveClosedFromMergeRequest < ActiveRecord::Migration - def up - remove_column :merge_requests, :closed - end - - def down - add_column :merge_requests, :closed, :boolean - end -end diff --git a/db/migrate/20130218141554_remove_closed_from_milestone.rb b/db/migrate/20130218141554_remove_closed_from_milestone.rb deleted file mode 100644 index e8dae4a19b1cb3fd235eb204ed46813e917c9810..0000000000000000000000000000000000000000 --- a/db/migrate/20130218141554_remove_closed_from_milestone.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveClosedFromMilestone < ActiveRecord::Migration - def up - remove_column :milestones, :closed - end - - def down - add_column :milestones, :closed, :boolean - end -end diff --git a/db/migrate/20130220124204_add_new_merge_status_to_merge_request.rb b/db/migrate/20130220124204_add_new_merge_status_to_merge_request.rb deleted file mode 100644 index d78bd0ae923c2627496096e2de2fe775b845d74c..0000000000000000000000000000000000000000 --- a/db/migrate/20130220124204_add_new_merge_status_to_merge_request.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNewMergeStatusToMergeRequest < ActiveRecord::Migration - def change - add_column :merge_requests, :new_merge_status, :string - end -end diff --git a/db/migrate/20130220125544_convert_merge_status_in_merge_request.rb b/db/migrate/20130220125544_convert_merge_status_in_merge_request.rb deleted file mode 100644 index b310b35e37314de1350f61771057cc541cd0ae22..0000000000000000000000000000000000000000 --- a/db/migrate/20130220125544_convert_merge_status_in_merge_request.rb +++ /dev/null @@ -1,17 +0,0 @@ -class ConvertMergeStatusInMergeRequest < ActiveRecord::Migration - def up - MergeRequest.transaction do - MergeRequest.where(merge_status: 1).update_all("new_merge_status = 'unchecked'") - MergeRequest.where(merge_status: 2).update_all("new_merge_status = 'can_be_merged'") - MergeRequest.where(merge_status: 3).update_all("new_merge_status = 'cannot_be_merged'") - end - end - - def down - MergeRequest.transaction do - MergeRequest.where(new_merge_status: :unchecked).update_all("merge_status = 1") - MergeRequest.where(new_merge_status: :can_be_merged).update_all("merge_status = 2") - MergeRequest.where(new_merge_status: :cannot_be_merged).update_all("merge_status = 3") - end - end -end diff --git a/db/migrate/20130220125545_remove_merge_status_from_merge_request.rb b/db/migrate/20130220125545_remove_merge_status_from_merge_request.rb deleted file mode 100644 index 9083183beb0dfb818c5eedcfc540888762acf8c4..0000000000000000000000000000000000000000 --- a/db/migrate/20130220125545_remove_merge_status_from_merge_request.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveMergeStatusFromMergeRequest < ActiveRecord::Migration - def up - remove_column :merge_requests, :merge_status - end - - def down - add_column :merge_requests, :merge_status, :integer - end -end diff --git a/db/migrate/20130220133245_rename_new_merge_status_to_merge_status_in_milestone.rb b/db/migrate/20130220133245_rename_new_merge_status_to_merge_status_in_milestone.rb deleted file mode 100644 index 3f8f38dc979af8fe0556bd78b9befb5124e9766e..0000000000000000000000000000000000000000 --- a/db/migrate/20130220133245_rename_new_merge_status_to_merge_status_in_milestone.rb +++ /dev/null @@ -1,5 +0,0 @@ -class RenameNewMergeStatusToMergeStatusInMilestone < ActiveRecord::Migration - def change - rename_column :merge_requests, :new_merge_status, :merge_status - end -end diff --git a/db/migrate/20130304104623_add_state_to_user.rb b/db/migrate/20130304104623_add_state_to_user.rb deleted file mode 100644 index 8154c21065f711403a241d218916146dd6f5e146..0000000000000000000000000000000000000000 --- a/db/migrate/20130304104623_add_state_to_user.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddStateToUser < ActiveRecord::Migration - def change - add_column :users, :state, :string - end -end diff --git a/db/migrate/20130304104740_convert_blocked_to_state.rb b/db/migrate/20130304104740_convert_blocked_to_state.rb deleted file mode 100644 index e8d5257ac96e88e49d3722d59dbf4c09ec2c87c9..0000000000000000000000000000000000000000 --- a/db/migrate/20130304104740_convert_blocked_to_state.rb +++ /dev/null @@ -1,14 +0,0 @@ -class ConvertBlockedToState < ActiveRecord::Migration - def up - User.transaction do - User.where(blocked: true).update_all(state: :blocked) - User.where(blocked: false).update_all(state: :active) - end - end - - def down - User.transaction do - User.where(state: :blocked).update_all(blocked: :true) - end - end -end diff --git a/db/migrate/20130304105317_remove_blocked_from_user.rb b/db/migrate/20130304105317_remove_blocked_from_user.rb deleted file mode 100644 index e010474538c5b22d76b7ec00ce030a3583b2a1b2..0000000000000000000000000000000000000000 --- a/db/migrate/20130304105317_remove_blocked_from_user.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveBlockedFromUser < ActiveRecord::Migration - def up - remove_column :users, :blocked - end - - def down - add_column :users, :blocked, :boolean - end -end diff --git a/db/migrate/20130315124931_user_color_scheme.rb b/db/migrate/20130315124931_user_color_scheme.rb deleted file mode 100644 index fe139e32ea72301461edc2d938ad4d65fc7572ed..0000000000000000000000000000000000000000 --- a/db/migrate/20130315124931_user_color_scheme.rb +++ /dev/null @@ -1,12 +0,0 @@ -class UserColorScheme < ActiveRecord::Migration - def up - add_column :users, :color_scheme_id, :integer, null: false, default: 1 - User.where(dark_scheme: true).update_all(color_scheme_id: 2) - remove_column :users, :dark_scheme - end - - def down - add_column :users, :dark_scheme, :boolean, null: false, default: false - remove_column :users, :color_scheme_id - end -end diff --git a/db/migrate/20130318212250_add_snippets_to_features.rb b/db/migrate/20130318212250_add_snippets_to_features.rb deleted file mode 100644 index ad0b4434c435301911b86e22a58144e231c5838a..0000000000000000000000000000000000000000 --- a/db/migrate/20130318212250_add_snippets_to_features.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddSnippetsToFeatures < ActiveRecord::Migration - def change - add_column :projects, :snippets_enabled, :boolean, null: false, default: true - end -end diff --git a/db/migrate/20130319214458_create_forked_project_links.rb b/db/migrate/20130319214458_create_forked_project_links.rb deleted file mode 100644 index f91afc26e77c5424ecf9b299c11933827a4d676b..0000000000000000000000000000000000000000 --- a/db/migrate/20130319214458_create_forked_project_links.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateForkedProjectLinks < ActiveRecord::Migration - def change - create_table :forked_project_links do |t| - t.integer :forked_to_project_id, null: false - t.integer :forked_from_project_id, null: false - - t.timestamps - end - add_index :forked_project_links, :forked_to_project_id, unique: true - end -end diff --git a/db/migrate/20130323174317_add_private_to_snippets.rb b/db/migrate/20130323174317_add_private_to_snippets.rb deleted file mode 100644 index 92f3a5c70118f7b4506aa0ac5d0fc63b3955bf78..0000000000000000000000000000000000000000 --- a/db/migrate/20130323174317_add_private_to_snippets.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPrivateToSnippets < ActiveRecord::Migration - def change - add_column :snippets, :private, :boolean, null: false, default: true - end -end diff --git a/db/migrate/20130324151736_add_type_to_snippets.rb b/db/migrate/20130324151736_add_type_to_snippets.rb deleted file mode 100644 index 276aab2ca1578e77c1c73e50e685c40f427de2ec..0000000000000000000000000000000000000000 --- a/db/migrate/20130324151736_add_type_to_snippets.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTypeToSnippets < ActiveRecord::Migration - def change - add_column :snippets, :type, :string - end -end diff --git a/db/migrate/20130324172327_change_project_id_to_null_in_snipepts.rb b/db/migrate/20130324172327_change_project_id_to_null_in_snipepts.rb deleted file mode 100644 index 4c992bac4d114eb2220ffbf7daccc404ea5e7009..0000000000000000000000000000000000000000 --- a/db/migrate/20130324172327_change_project_id_to_null_in_snipepts.rb +++ /dev/null @@ -1,9 +0,0 @@ -class ChangeProjectIdToNullInSnipepts < ActiveRecord::Migration - def up - change_column :snippets, :project_id, :integer, :null => true - end - - def down - change_column :snippets, :project_id, :integer, :null => false - end -end diff --git a/db/migrate/20130324203535_add_type_value_for_snippets.rb b/db/migrate/20130324203535_add_type_value_for_snippets.rb deleted file mode 100644 index 8c05dd2cc717946e6352968e219cd121e458e439..0000000000000000000000000000000000000000 --- a/db/migrate/20130324203535_add_type_value_for_snippets.rb +++ /dev/null @@ -1,8 +0,0 @@ -class AddTypeValueForSnippets < ActiveRecord::Migration - def up - Snippet.where("project_id IS NOT NULL").update_all(type: 'ProjectSnippet') - end - - def down - end -end diff --git a/db/migrate/20130325173941_add_notification_level_to_user.rb b/db/migrate/20130325173941_add_notification_level_to_user.rb deleted file mode 100644 index 9f466e38c13648c80b884bf2225c976167bc6973..0000000000000000000000000000000000000000 --- a/db/migrate/20130325173941_add_notification_level_to_user.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNotificationLevelToUser < ActiveRecord::Migration - def change - add_column :users, :notification_level, :integer, null: false, default: 1 - end -end diff --git a/db/migrate/20130326142630_add_index_to_users_authentication_token.rb b/db/migrate/20130326142630_add_index_to_users_authentication_token.rb deleted file mode 100644 index d42ef113738aad4a3bd4a9b4bf6d572b36199976..0000000000000000000000000000000000000000 --- a/db/migrate/20130326142630_add_index_to_users_authentication_token.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIndexToUsersAuthenticationToken < ActiveRecord::Migration - def change - add_index :users, :authentication_token, unique: true - end -end diff --git a/db/migrate/20130403003950_add_last_activity_column_into_project.rb b/db/migrate/20130403003950_add_last_activity_column_into_project.rb deleted file mode 100644 index 2a036bd99938652ad8ef6fbad45c6e3738da4842..0000000000000000000000000000000000000000 --- a/db/migrate/20130403003950_add_last_activity_column_into_project.rb +++ /dev/null @@ -1,21 +0,0 @@ -class AddLastActivityColumnIntoProject < ActiveRecord::Migration - def up - add_column :projects, :last_activity_at, :datetime - add_index :projects, :last_activity_at - - Project.find_each do |project| - last_activity_date = if project.last_activity - project.last_activity.created_at - else - project.updated_at - end - - project.update_attribute(:last_activity_at, last_activity_date) - end - end - - def down - remove_index :projects, :last_activity_at - remove_column :projects, :last_activity_at - end -end diff --git a/db/migrate/20130404164628_add_notification_level_to_user_project.rb b/db/migrate/20130404164628_add_notification_level_to_user_project.rb deleted file mode 100644 index 27de5d6bf55704d138476271967ab6fc4a44d4cc..0000000000000000000000000000000000000000 --- a/db/migrate/20130404164628_add_notification_level_to_user_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNotificationLevelToUserProject < ActiveRecord::Migration - def change - add_column :users_projects, :notification_level, :integer, null: false, default: 3 - end -end diff --git a/db/migrate/20130410175022_remove_wiki_table.rb b/db/migrate/20130410175022_remove_wiki_table.rb deleted file mode 100644 index 9077aa2473c09da1085811efe110e169f5a85866..0000000000000000000000000000000000000000 --- a/db/migrate/20130410175022_remove_wiki_table.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveWikiTable < ActiveRecord::Migration - def up - drop_table :wikis - end - - def down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/migrate/20130419190306_allow_merges_for_forks.rb b/db/migrate/20130419190306_allow_merges_for_forks.rb deleted file mode 100644 index 56ce58a846dba43d724635aaaeb7b16d7a0ee2a4..0000000000000000000000000000000000000000 --- a/db/migrate/20130419190306_allow_merges_for_forks.rb +++ /dev/null @@ -1,13 +0,0 @@ -class AllowMergesForForks < ActiveRecord::Migration - def self.up - add_column :merge_requests, :target_project_id, :integer, :null => true - MergeRequest.update_all("target_project_id = project_id") - change_column :merge_requests, :target_project_id, :integer, :null => false - rename_column :merge_requests, :project_id, :source_project_id - end - - def self.down - remove_column :merge_requests, :target_project_id - rename_column :merge_requests, :source_project_id,:project_id - end -end diff --git a/db/migrate/20130506085413_add_type_to_key.rb b/db/migrate/20130506085413_add_type_to_key.rb deleted file mode 100644 index 315e7ca77b3c2d7b5cc62260e7eb7404f069b7f1..0000000000000000000000000000000000000000 --- a/db/migrate/20130506085413_add_type_to_key.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTypeToKey < ActiveRecord::Migration - def change - add_column :keys, :type, :string - end -end diff --git a/db/migrate/20130506090604_create_deploy_keys_projects.rb b/db/migrate/20130506090604_create_deploy_keys_projects.rb deleted file mode 100644 index 0dc8cdeb07dc4805a4eda6d1c777c226c6434306..0000000000000000000000000000000000000000 --- a/db/migrate/20130506090604_create_deploy_keys_projects.rb +++ /dev/null @@ -1,10 +0,0 @@ -class CreateDeployKeysProjects < ActiveRecord::Migration - def change - create_table :deploy_keys_projects do |t| - t.integer :deploy_key_id, null: false - t.integer :project_id, null: false - - t.timestamps - end - end -end diff --git a/db/migrate/20130506095501_remove_project_id_from_key.rb b/db/migrate/20130506095501_remove_project_id_from_key.rb deleted file mode 100644 index 6b794cfb5c133e7d717824c3c592a95ca9130bed..0000000000000000000000000000000000000000 --- a/db/migrate/20130506095501_remove_project_id_from_key.rb +++ /dev/null @@ -1,22 +0,0 @@ -class RemoveProjectIdFromKey < ActiveRecord::Migration - def up - puts 'Migrate deploy keys: ' - Key.where('project_id IS NOT NULL').update_all(type: 'DeployKey') - - DeployKey.all.each do |key| - project = Project.find_by(id: key.project_id) - if project - project.deploy_keys << key - print '.' - end - end - - puts 'Done' - - remove_column :keys, :project_id - end - - def down - add_column :keys, :project_id, :integer - end -end diff --git a/db/migrate/20130522141856_add_more_fields_to_service.rb b/db/migrate/20130522141856_add_more_fields_to_service.rb deleted file mode 100644 index 298e902df2f9284701c4260db1ac92c6706071fa..0000000000000000000000000000000000000000 --- a/db/migrate/20130522141856_add_more_fields_to_service.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddMoreFieldsToService < ActiveRecord::Migration - def change - add_column :services, :subdomain, :string - add_column :services, :room, :string - end -end diff --git a/db/migrate/20130528184641_add_system_to_notes.rb b/db/migrate/20130528184641_add_system_to_notes.rb deleted file mode 100644 index 1b22a4934f992d8c4ae109456a1ab4f6d014a12b..0000000000000000000000000000000000000000 --- a/db/migrate/20130528184641_add_system_to_notes.rb +++ /dev/null @@ -1,16 +0,0 @@ -class AddSystemToNotes < ActiveRecord::Migration - class Note < ActiveRecord::Base - end - - def up - add_column :notes, :system, :boolean, default: false, null: false - - Note.reset_column_information - Note.update_all(system: false) - Note.where("note like '_status changed to%'").update_all(system: true) - end - - def down - remove_column :notes, :system - end -end diff --git a/db/migrate/20130611210815_increase_snippet_text_column_size.rb b/db/migrate/20130611210815_increase_snippet_text_column_size.rb deleted file mode 100644 index f7b4447e43e8ba8348fcc5e6617126454bcf851c..0000000000000000000000000000000000000000 --- a/db/migrate/20130611210815_increase_snippet_text_column_size.rb +++ /dev/null @@ -1,9 +0,0 @@ -class IncreaseSnippetTextColumnSize < ActiveRecord::Migration - def up - # MYSQL LARGETEXT for snippet - change_column :snippets, :content, :text, :limit => 4294967295 - end - - def down - end -end diff --git a/db/migrate/20130613165816_add_password_expires_at_to_users.rb b/db/migrate/20130613165816_add_password_expires_at_to_users.rb deleted file mode 100644 index 3479c8e64d015209582639749271400e0ab873a9..0000000000000000000000000000000000000000 --- a/db/migrate/20130613165816_add_password_expires_at_to_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPasswordExpiresAtToUsers < ActiveRecord::Migration - def change - add_column :users, :password_expires_at, :datetime - end -end diff --git a/db/migrate/20130613173246_add_created_by_id_to_user.rb b/db/migrate/20130613173246_add_created_by_id_to_user.rb deleted file mode 100644 index 615e96eb156d8f58d20eb20d61b85b670325fa98..0000000000000000000000000000000000000000 --- a/db/migrate/20130613173246_add_created_by_id_to_user.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddCreatedByIdToUser < ActiveRecord::Migration - def change - add_column :users, :created_by_id, :integer - end -end diff --git a/db/migrate/20130614132337_add_improted_to_project.rb b/db/migrate/20130614132337_add_improted_to_project.rb deleted file mode 100644 index cc882c3f10a596cae19af15cd8514958b6c40d30..0000000000000000000000000000000000000000 --- a/db/migrate/20130614132337_add_improted_to_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddImprotedToProject < ActiveRecord::Migration - def change - add_column :projects, :imported, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20130617095603_create_users_groups.rb b/db/migrate/20130617095603_create_users_groups.rb deleted file mode 100644 index 2efc04f1151e04ffa5f80f8952113d9ec73a749a..0000000000000000000000000000000000000000 --- a/db/migrate/20130617095603_create_users_groups.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateUsersGroups < ActiveRecord::Migration - def change - create_table :users_groups do |t| - t.integer :group_access, null: false - t.integer :group_id, null: false - t.integer :user_id, null: false - - t.timestamps - end - end -end diff --git a/db/migrate/20130621195223_add_notification_level_to_user_group.rb b/db/migrate/20130621195223_add_notification_level_to_user_group.rb deleted file mode 100644 index 8c2e3dfcaca2e28dd8ba0503b8ab66ec040accc8..0000000000000000000000000000000000000000 --- a/db/migrate/20130621195223_add_notification_level_to_user_group.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNotificationLevelToUserGroup < ActiveRecord::Migration - def change - add_column :users_groups, :notification_level, :integer, null: false, default: 3 - end -end diff --git a/db/migrate/20130622115340_add_more_db_index.rb b/db/migrate/20130622115340_add_more_db_index.rb deleted file mode 100644 index 9570a7a3f1e60add51ab296789059a2ccc88188e..0000000000000000000000000000000000000000 --- a/db/migrate/20130622115340_add_more_db_index.rb +++ /dev/null @@ -1,12 +0,0 @@ -class AddMoreDbIndex < ActiveRecord::Migration - def change - add_index :deploy_keys_projects, :project_id - add_index :web_hooks, :project_id - add_index :protected_branches, :project_id - - add_index :users_groups, :user_id - add_index :snippets, :author_id - add_index :notes, :author_id - add_index :notes, [:noteable_id, :noteable_type] - end -end diff --git a/db/migrate/20130624162710_add_fingerprint_to_key.rb b/db/migrate/20130624162710_add_fingerprint_to_key.rb deleted file mode 100644 index 544a83667275043c851b3c05d5a99cbb2f0369e3..0000000000000000000000000000000000000000 --- a/db/migrate/20130624162710_add_fingerprint_to_key.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddFingerprintToKey < ActiveRecord::Migration - def change - add_column :keys, :fingerprint, :string - remove_column :keys, :identifier - end -end diff --git a/db/migrate/20130804151314_add_st_diff_to_note.rb b/db/migrate/20130804151314_add_st_diff_to_note.rb deleted file mode 100644 index 3f9abb975c387ffdd504d2c348f053c9eca2aa24..0000000000000000000000000000000000000000 --- a/db/migrate/20130804151314_add_st_diff_to_note.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddStDiffToNote < ActiveRecord::Migration - def change - add_column :notes, :st_diff, :text, :null => true - end -end diff --git a/db/migrate/20130809124851_add_permission_check_to_user.rb b/db/migrate/20130809124851_add_permission_check_to_user.rb deleted file mode 100644 index c26157904c7348cb193810a61bc5f7e6fa30a2a9..0000000000000000000000000000000000000000 --- a/db/migrate/20130809124851_add_permission_check_to_user.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPermissionCheckToUser < ActiveRecord::Migration - def change - add_column :users, :last_credential_check_at, :datetime - end -end diff --git a/db/migrate/20130812143708_add_import_url_to_project.rb b/db/migrate/20130812143708_add_import_url_to_project.rb deleted file mode 100644 index 023a48741b263204067297495382f1b6d6fbcea5..0000000000000000000000000000000000000000 --- a/db/migrate/20130812143708_add_import_url_to_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddImportUrlToProject < ActiveRecord::Migration - def change - add_column :projects, :import_url, :string - end -end diff --git a/db/migrate/20130819182730_add_internal_ids_to_issues_and_mr.rb b/db/migrate/20130819182730_add_internal_ids_to_issues_and_mr.rb deleted file mode 100644 index e55ae38f144d5f4f181fa5a9b287834ec73f00fb..0000000000000000000000000000000000000000 --- a/db/migrate/20130819182730_add_internal_ids_to_issues_and_mr.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddInternalIdsToIssuesAndMr < ActiveRecord::Migration - def change - add_column :issues, :iid, :integer - add_column :merge_requests, :iid, :integer - end -end diff --git a/db/migrate/20130821090530_remove_deprecated_tables.rb b/db/migrate/20130821090530_remove_deprecated_tables.rb deleted file mode 100644 index 539c0617eeb7747e851da95d6ba6b5b96934c73f..0000000000000000000000000000000000000000 --- a/db/migrate/20130821090530_remove_deprecated_tables.rb +++ /dev/null @@ -1,11 +0,0 @@ -class RemoveDeprecatedTables < ActiveRecord::Migration - def up - drop_table :user_teams - drop_table :user_team_project_relationships - drop_table :user_team_user_relationships - end - - def down - raise 'No rollback for this migration' - end -end diff --git a/db/migrate/20130821090531_add_internal_ids_to_milestones.rb b/db/migrate/20130821090531_add_internal_ids_to_milestones.rb deleted file mode 100644 index 33e5bae580552a984fbb84e91ef94b1a3f4003f3..0000000000000000000000000000000000000000 --- a/db/migrate/20130821090531_add_internal_ids_to_milestones.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddInternalIdsToMilestones < ActiveRecord::Migration - def change - add_column :milestones, :iid, :integer - end -end diff --git a/db/migrate/20130909132950_add_description_to_merge_request.rb b/db/migrate/20130909132950_add_description_to_merge_request.rb deleted file mode 100644 index 9bcd0c7ee0689122e979b5ea63f7b04a0348f768..0000000000000000000000000000000000000000 --- a/db/migrate/20130909132950_add_description_to_merge_request.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddDescriptionToMergeRequest < ActiveRecord::Migration - def change - add_column :merge_requests, :description, :text, null: true - end -end diff --git a/db/migrate/20130926081215_change_owner_id_for_group.rb b/db/migrate/20130926081215_change_owner_id_for_group.rb deleted file mode 100644 index 8f1992c37ab0bb51c4b54c0e8b82da7798fce568..0000000000000000000000000000000000000000 --- a/db/migrate/20130926081215_change_owner_id_for_group.rb +++ /dev/null @@ -1,9 +0,0 @@ -class ChangeOwnerIdForGroup < ActiveRecord::Migration - def up - change_column :namespaces, :owner_id, :integer, null: true - end - - def down - change_column :namespaces, :owner_id, :integer, null: false - end -end diff --git a/db/migrate/20131005191208_add_avatar_to_users.rb b/db/migrate/20131005191208_add_avatar_to_users.rb deleted file mode 100644 index 7b4de37ad72369481793ec72a1ce99ec867f21ba..0000000000000000000000000000000000000000 --- a/db/migrate/20131005191208_add_avatar_to_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddAvatarToUsers < ActiveRecord::Migration - def change - add_column :users, :avatar, :string - end -end diff --git a/db/migrate/20131009115346_add_confirmable_to_users.rb b/db/migrate/20131009115346_add_confirmable_to_users.rb deleted file mode 100644 index 249cbe704ed678596bee82a744218c97ee4253dd..0000000000000000000000000000000000000000 --- a/db/migrate/20131009115346_add_confirmable_to_users.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddConfirmableToUsers < ActiveRecord::Migration - def self.up - add_column :users, :confirmation_token, :string - add_column :users, :confirmed_at, :datetime - add_column :users, :confirmation_sent_at, :datetime - add_column :users, :unconfirmed_email, :string - add_index :users, :confirmation_token, unique: true - User.update_all(confirmed_at: Time.now) - end - - def self.down - remove_column :users, :confirmation_token, :confirmed_at, :confirmation_sent_at - remove_column :users, :unconfirmed_email - end -end diff --git a/db/migrate/20131106151520_remove_default_branch.rb b/db/migrate/20131106151520_remove_default_branch.rb deleted file mode 100644 index 88a890eb3eb7e759ced674d594f3218d57a91efe..0000000000000000000000000000000000000000 --- a/db/migrate/20131106151520_remove_default_branch.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveDefaultBranch < ActiveRecord::Migration - def up - remove_column :projects, :default_branch - end - - def down - add_column :projects, :default_branch, :string - end -end diff --git a/db/migrate/20131112114325_create_broadcast_messages.rb b/db/migrate/20131112114325_create_broadcast_messages.rb deleted file mode 100644 index 147178e9dcf2dc7d490f82507aa6fe144f449cf3..0000000000000000000000000000000000000000 --- a/db/migrate/20131112114325_create_broadcast_messages.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateBroadcastMessages < ActiveRecord::Migration - def change - create_table :broadcast_messages do |t| - t.text :message, null: false - t.datetime :starts_at - t.datetime :ends_at - t.integer :alert_type - - t.timestamps - end - end -end diff --git a/db/migrate/20131112220935_add_visibility_level_to_projects.rb b/db/migrate/20131112220935_add_visibility_level_to_projects.rb deleted file mode 100644 index cf1e9f912a04957ee92486d189ae1edf74ddd83f..0000000000000000000000000000000000000000 --- a/db/migrate/20131112220935_add_visibility_level_to_projects.rb +++ /dev/null @@ -1,13 +0,0 @@ -class AddVisibilityLevelToProjects < ActiveRecord::Migration - def self.up - add_column :projects, :visibility_level, :integer, :default => 0, :null => false - Project.where(public: true).update_all(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - remove_column :projects, :public - end - - def self.down - add_column :projects, :public, :boolean, :default => false, :null => false - Project.where(visibility_level: Gitlab::VisibilityLevel::PUBLIC).update_all(public: true) - remove_column :projects, :visibility_level - end -end diff --git a/db/migrate/20131129154016_add_archived_to_projects.rb b/db/migrate/20131129154016_add_archived_to_projects.rb deleted file mode 100644 index 917e690ba477d552aa6cbbc79ffdd490441c87bd..0000000000000000000000000000000000000000 --- a/db/migrate/20131129154016_add_archived_to_projects.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddArchivedToProjects < ActiveRecord::Migration - def change - add_column :projects, :archived, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20131130165425_add_color_and_font_to_broadcast_messages.rb b/db/migrate/20131130165425_add_color_and_font_to_broadcast_messages.rb deleted file mode 100644 index 473f355eceb0566f4caf97ce575770d95dc5e690..0000000000000000000000000000000000000000 --- a/db/migrate/20131130165425_add_color_and_font_to_broadcast_messages.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddColorAndFontToBroadcastMessages < ActiveRecord::Migration - def change - add_column :broadcast_messages, :color, :string - add_column :broadcast_messages, :font, :string - end -end diff --git a/db/migrate/20131202192556_add_event_fields_for_web_hook.rb b/db/migrate/20131202192556_add_event_fields_for_web_hook.rb deleted file mode 100644 index d29e996852ec3e9a1f8e8f215a9ecfd74ec421fa..0000000000000000000000000000000000000000 --- a/db/migrate/20131202192556_add_event_fields_for_web_hook.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddEventFieldsForWebHook < ActiveRecord::Migration - def change - add_column :web_hooks, :push_events, :boolean, default: true, null: false - add_column :web_hooks, :issues_events, :boolean, default: false, null: false - add_column :web_hooks, :merge_requests_events, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20131214224427_add_hide_no_ssh_key_to_users.rb b/db/migrate/20131214224427_add_hide_no_ssh_key_to_users.rb deleted file mode 100644 index 7cec79e7ee823547e9b6c026198b0c97581e3d84..0000000000000000000000000000000000000000 --- a/db/migrate/20131214224427_add_hide_no_ssh_key_to_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddHideNoSshKeyToUsers < ActiveRecord::Migration - def change - add_column :users, :hide_no_ssh_key, :boolean, :default => false - end -end diff --git a/db/migrate/20131217102743_add_recipients_to_service.rb b/db/migrate/20131217102743_add_recipients_to_service.rb deleted file mode 100644 index 9695c25135202edacea014e237179a4fb1ee62fa..0000000000000000000000000000000000000000 --- a/db/migrate/20131217102743_add_recipients_to_service.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddRecipientsToService < ActiveRecord::Migration - def change - add_column :services, :recipients, :text - end -end diff --git a/db/migrate/20140116231608_add_website_url_to_users.rb b/db/migrate/20140116231608_add_website_url_to_users.rb deleted file mode 100644 index 0996fdcad73257dc31b728a2da9564b4715626c2..0000000000000000000000000000000000000000 --- a/db/migrate/20140116231608_add_website_url_to_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddWebsiteUrlToUsers < ActiveRecord::Migration - def change - add_column :users, :website_url, :string, {:null => false, :default => ''} - end -end diff --git a/db/migrate/20140122112253_create_merge_request_diffs.rb b/db/migrate/20140122112253_create_merge_request_diffs.rb deleted file mode 100644 index ef592305a23a9488f666f8a98d8297cd28d8a815..0000000000000000000000000000000000000000 --- a/db/migrate/20140122112253_create_merge_request_diffs.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateMergeRequestDiffs < ActiveRecord::Migration - def change - create_table :merge_request_diffs do |t| - t.string :state, null: false, default: 'collected' - t.text :st_commits, null: true, limit: 2147483647 - t.text :st_diffs, null: true, limit: 2147483647 - t.integer :merge_request_id, null: false - - t.timestamps - end - end -end diff --git a/db/migrate/20140122114406_migrate_mr_diffs.rb b/db/migrate/20140122114406_migrate_mr_diffs.rb deleted file mode 100644 index 1595e2b64725923ee02c0f65a65d25144f573f47..0000000000000000000000000000000000000000 --- a/db/migrate/20140122114406_migrate_mr_diffs.rb +++ /dev/null @@ -1,9 +0,0 @@ -class MigrateMrDiffs < ActiveRecord::Migration - def self.up - execute "INSERT INTO merge_request_diffs ( merge_request_id, st_commits, st_diffs ) SELECT id, st_commits, st_diffs FROM merge_requests" - end - - def self.down - MergeRequestDiff.delete_all - end -end diff --git a/db/migrate/20140122122549_remove_m_rdiff_fields.rb b/db/migrate/20140122122549_remove_m_rdiff_fields.rb deleted file mode 100644 index 8f863d85a684909d886a7ee67685b28aca190749..0000000000000000000000000000000000000000 --- a/db/migrate/20140122122549_remove_m_rdiff_fields.rb +++ /dev/null @@ -1,21 +0,0 @@ -class RemoveMRdiffFields < ActiveRecord::Migration - def up - remove_column :merge_requests, :st_commits - remove_column :merge_requests, :st_diffs - end - - def down - add_column :merge_requests, :st_commits, :text, null: true, limit: 2147483647 - add_column :merge_requests, :st_diffs, :text, null: true, limit: 2147483647 - - if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' - execute "UPDATE merge_requests mr - SET (st_commits, st_diffs) = (md.st_commits, md.st_diffs) - FROM merge_request_diffs md - WHERE md.merge_request_id = mr.id" - else - execute "UPDATE merge_requests mr, merge_request_diffs md SET mr.st_commits = md.st_commits WHERE md.merge_request_id = mr.id" - execute "UPDATE merge_requests mr, merge_request_diffs md SET mr.st_diffs = md.st_diffs WHERE md.merge_request_id = mr.id" - end - end -end diff --git a/db/migrate/20140125162722_add_avatar_to_projects.rb b/db/migrate/20140125162722_add_avatar_to_projects.rb deleted file mode 100644 index 9523ac722f2fa2144759e3cd268374eb1747e322..0000000000000000000000000000000000000000 --- a/db/migrate/20140125162722_add_avatar_to_projects.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddAvatarToProjects < ActiveRecord::Migration - def change - add_column :projects, :avatar, :string - end -end diff --git a/db/migrate/20140127170938_add_group_avatars.rb b/db/migrate/20140127170938_add_group_avatars.rb deleted file mode 100644 index 2911096dd5d300268d1efeedb3510a368d5bc8a3..0000000000000000000000000000000000000000 --- a/db/migrate/20140127170938_add_group_avatars.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddGroupAvatars < ActiveRecord::Migration - def change - add_column :namespaces, :avatar, :string - end -end diff --git a/db/migrate/20140209025651_create_emails.rb b/db/migrate/20140209025651_create_emails.rb deleted file mode 100644 index cb78c4af11b25b59533c2d15a33292c01920eb3d..0000000000000000000000000000000000000000 --- a/db/migrate/20140209025651_create_emails.rb +++ /dev/null @@ -1,13 +0,0 @@ -class CreateEmails < ActiveRecord::Migration - def change - create_table :emails do |t| - t.integer :user_id, null: false - t.string :email, null: false - - t.timestamps - end - - add_index :emails, :user_id - add_index :emails, :email, unique: true - end -end diff --git a/db/migrate/20140214102325_add_api_key_to_services.rb b/db/migrate/20140214102325_add_api_key_to_services.rb deleted file mode 100644 index 30eeca2c1f65c05999eaad5f65d6b4e0b2393d9e..0000000000000000000000000000000000000000 --- a/db/migrate/20140214102325_add_api_key_to_services.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddApiKeyToServices < ActiveRecord::Migration - def change - add_column :services, :api_key, :string - end -end diff --git a/db/migrate/20140304005354_add_index_merge_request_diffs_on_merge_request_id.rb b/db/migrate/20140304005354_add_index_merge_request_diffs_on_merge_request_id.rb deleted file mode 100644 index 65d28e8cb01f1afeb4bed9ffe660bf48e90f6f48..0000000000000000000000000000000000000000 --- a/db/migrate/20140304005354_add_index_merge_request_diffs_on_merge_request_id.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIndexMergeRequestDiffsOnMergeRequestId < ActiveRecord::Migration - def change - add_index :merge_request_diffs, :merge_request_id, unique: true - end -end diff --git a/db/migrate/20140305193308_add_tag_push_hooks_to_project_hook.rb b/db/migrate/20140305193308_add_tag_push_hooks_to_project_hook.rb deleted file mode 100644 index 7017148702a4013e27b5627865454fe18fff292c..0000000000000000000000000000000000000000 --- a/db/migrate/20140305193308_add_tag_push_hooks_to_project_hook.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTagPushHooksToProjectHook < ActiveRecord::Migration - def change - add_column :web_hooks, :tag_push_events, :boolean, default: false - end -end diff --git a/db/migrate/20140312145357_add_import_status_to_project.rb b/db/migrate/20140312145357_add_import_status_to_project.rb deleted file mode 100644 index ef972e8342a0e4f0105dc8aabc5f98d4f1e344b2..0000000000000000000000000000000000000000 --- a/db/migrate/20140312145357_add_import_status_to_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddImportStatusToProject < ActiveRecord::Migration - def change - add_column :projects, :import_status, :string - end -end diff --git a/db/migrate/20140313092127_migrate_already_imported_projects.rb b/db/migrate/20140313092127_migrate_already_imported_projects.rb deleted file mode 100644 index f4392c0f05e8db595c9cd3524623d109b2c3dd52..0000000000000000000000000000000000000000 --- a/db/migrate/20140313092127_migrate_already_imported_projects.rb +++ /dev/null @@ -1,12 +0,0 @@ -class MigrateAlreadyImportedProjects < ActiveRecord::Migration - def up - Project.where(imported: true).update_all(import_status: "finished") - Project.where(imported: false).update_all(import_status: "none") - remove_column :projects, :imported - end - - def down - add_column :projects, :imported, :boolean, default: false - Project.where(import_status: 'finished').update_all(imported: true) - end -end diff --git a/db/migrate/20140407135544_fix_namespaces.rb b/db/migrate/20140407135544_fix_namespaces.rb deleted file mode 100644 index 59665d538f00917d2a885f70801cda1683a8a930..0000000000000000000000000000000000000000 --- a/db/migrate/20140407135544_fix_namespaces.rb +++ /dev/null @@ -1,10 +0,0 @@ -class FixNamespaces < ActiveRecord::Migration - def up - Namespace.where('name <> path and type is null').each do |namespace| - namespace.update_attribute(:name, namespace.path) - end - end - - def down - end -end diff --git a/db/migrate/20140414131055_change_state_to_allow_empty_merge_request_diffs.rb b/db/migrate/20140414131055_change_state_to_allow_empty_merge_request_diffs.rb deleted file mode 100644 index 1f6d85d5f66ce0d0773d4bac461b0dcf50fe5310..0000000000000000000000000000000000000000 --- a/db/migrate/20140414131055_change_state_to_allow_empty_merge_request_diffs.rb +++ /dev/null @@ -1,11 +0,0 @@ -class ChangeStateToAllowEmptyMergeRequestDiffs < ActiveRecord::Migration - def up - change_column :merge_request_diffs, :state, :string, null: true, - default: nil - end - - def down - change_column :merge_request_diffs, :state, :string, null: false, - default: 'collected' - end -end diff --git a/db/migrate/20140415124820_limits_to_mysql.rb b/db/migrate/20140415124820_limits_to_mysql.rb deleted file mode 100644 index 3f6e62617c57ab82367fafd407c89815c504c34d..0000000000000000000000000000000000000000 --- a/db/migrate/20140415124820_limits_to_mysql.rb +++ /dev/null @@ -1 +0,0 @@ -require_relative 'limits_to_mysql' diff --git a/db/migrate/20140416074002_add_index_on_iid.rb b/db/migrate/20140416074002_add_index_on_iid.rb deleted file mode 100644 index 85269e2a03b3be385cdca8d69d0b0635b06ca73e..0000000000000000000000000000000000000000 --- a/db/migrate/20140416074002_add_index_on_iid.rb +++ /dev/null @@ -1,32 +0,0 @@ -class AddIndexOnIid < ActiveRecord::Migration - def change - RemoveDuplicateIid.clean(Issue) - RemoveDuplicateIid.clean(MergeRequest, 'target_project_id') - RemoveDuplicateIid.clean(Milestone) - - add_index :issues, [:project_id, :iid], unique: true - add_index :merge_requests, [:target_project_id, :iid], unique: true - add_index :milestones, [:project_id, :iid], unique: true - end -end - -class RemoveDuplicateIid - def self.clean(klass, project_field = 'project_id') - duplicates = klass.find_by_sql("SELECT iid, #{project_field} FROM #{klass.table_name} GROUP BY #{project_field}, iid HAVING COUNT(*) > 1") - - duplicates.each do |duplicate| - project_id = duplicate.send(project_field) - iid = duplicate.iid - items = klass.of_projects(project_id).where(iid: iid) - - if items.size > 1 - puts "Remove #{klass.name} duplicates for iid: #{iid} and project_id: #{project_id}" - items.shift - items.each do |item| - item.destroy - puts '.' - end - end - end - end -end diff --git a/db/migrate/20140416185734_index_on_current_sign_in_at.rb b/db/migrate/20140416185734_index_on_current_sign_in_at.rb deleted file mode 100644 index 0bf80ce154a151366967d45921bcebef5bcbe143..0000000000000000000000000000000000000000 --- a/db/migrate/20140416185734_index_on_current_sign_in_at.rb +++ /dev/null @@ -1,5 +0,0 @@ -class IndexOnCurrentSignInAt < ActiveRecord::Migration - def change - add_index :users, :current_sign_in_at - end -end diff --git a/db/migrate/20140428105831_add_notes_index_updated_at.rb b/db/migrate/20140428105831_add_notes_index_updated_at.rb deleted file mode 100644 index 6c25570f128141919bee9e459d9690a4b63cb445..0000000000000000000000000000000000000000 --- a/db/migrate/20140428105831_add_notes_index_updated_at.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNotesIndexUpdatedAt < ActiveRecord::Migration - def change - add_index :notes, :updated_at - end -end diff --git a/db/migrate/20140502115131_add_repo_size_to_db.rb b/db/migrate/20140502115131_add_repo_size_to_db.rb deleted file mode 100644 index 7361d1a9440f3592bdff0d3235df55a365ebd115..0000000000000000000000000000000000000000 --- a/db/migrate/20140502115131_add_repo_size_to_db.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddRepoSizeToDb < ActiveRecord::Migration - def change - add_column :projects, :repository_size, :float, default: 0 - end -end diff --git a/db/migrate/20140502125220_migrate_repo_size.rb b/db/migrate/20140502125220_migrate_repo_size.rb deleted file mode 100644 index eed6d366814c5e956a0ee7fe7d5bd8bc974ff6d3..0000000000000000000000000000000000000000 --- a/db/migrate/20140502125220_migrate_repo_size.rb +++ /dev/null @@ -1,21 +0,0 @@ -class MigrateRepoSize < ActiveRecord::Migration - def up - Project.reset_column_information - Project.find_each(batch_size: 500) do |project| - begin - if project.empty_repo? - print '-' - else - project.update_repository_size - print '.' - end - rescue - print 'F' - end - end - puts 'Done' - end - - def down - end -end diff --git a/db/migrate/20140611135229_add_position_to_merge_request.rb b/db/migrate/20140611135229_add_position_to_merge_request.rb deleted file mode 100644 index d5fdecd0c39a04ba11739894974ffa9051b9e5ff..0000000000000000000000000000000000000000 --- a/db/migrate/20140611135229_add_position_to_merge_request.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPositionToMergeRequest < ActiveRecord::Migration - def change - add_column :merge_requests, :position, :integer, default: 0 - end -end diff --git a/db/migrate/20140625115202_create_users_star_projects.rb b/db/migrate/20140625115202_create_users_star_projects.rb deleted file mode 100644 index 412f0f6f34be75240d3f66552239a9c04d596f2c..0000000000000000000000000000000000000000 --- a/db/migrate/20140625115202_create_users_star_projects.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateUsersStarProjects < ActiveRecord::Migration - def change - create_table :users_star_projects do |t| - t.integer :project_id, null: false - t.integer :user_id, null: false - t.timestamps - end - add_index :users_star_projects, :user_id - add_index :users_star_projects, :project_id - add_index :users_star_projects, [:user_id, :project_id], unique: true - - add_column :projects, :star_count, :integer, default: 0, null: false - add_index :projects, :star_count, using: :btree - end -end diff --git a/db/migrate/20140729134820_create_labels.rb b/db/migrate/20140729134820_create_labels.rb deleted file mode 100644 index 3a4b6a152dc2f9a1c61401336692073b66d54376..0000000000000000000000000000000000000000 --- a/db/migrate/20140729134820_create_labels.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateLabels < ActiveRecord::Migration - def change - create_table :labels do |t| - t.string :title - t.string :color - t.integer :project_id - - t.timestamps - end - end -end diff --git a/db/migrate/20140729140420_create_label_links.rb b/db/migrate/20140729140420_create_label_links.rb deleted file mode 100644 index 2bfc4ae2094628d0d507d41824501183ed92ebfa..0000000000000000000000000000000000000000 --- a/db/migrate/20140729140420_create_label_links.rb +++ /dev/null @@ -1,11 +0,0 @@ -class CreateLabelLinks < ActiveRecord::Migration - def change - create_table :label_links do |t| - t.integer :label_id - t.integer :target_id - t.string :target_type - - t.timestamps - end - end -end diff --git a/db/migrate/20140729145339_migrate_project_tags.rb b/db/migrate/20140729145339_migrate_project_tags.rb deleted file mode 100644 index 5760e4bfeaa85054dc04c24741d60f588b972a27..0000000000000000000000000000000000000000 --- a/db/migrate/20140729145339_migrate_project_tags.rb +++ /dev/null @@ -1,9 +0,0 @@ -class MigrateProjectTags < ActiveRecord::Migration - def up - ActsAsTaggableOn::Tagging.where(taggable_type: 'Project', context: 'labels').update_all(context: 'tags') - end - - def down - ActsAsTaggableOn::Tagging.where(taggable_type: 'Project', context: 'tags').update_all(context: 'labels') - end -end diff --git a/db/migrate/20140729152420_migrate_taggable_labels.rb b/db/migrate/20140729152420_migrate_taggable_labels.rb deleted file mode 100644 index dc28d727d9a450ad9bffcedc256f062363870d19..0000000000000000000000000000000000000000 --- a/db/migrate/20140729152420_migrate_taggable_labels.rb +++ /dev/null @@ -1,35 +0,0 @@ -class MigrateTaggableLabels < ActiveRecord::Migration - def up - taggings = ActsAsTaggableOn::Tagging.where(taggable_type: ['Issue', 'MergeRequest'], context: 'labels') - taggings.find_each(batch_size: 500) do |tagging| - # Clean up orphaned taggings while we are here - if tagging.taggable.blank? || tagging.tag.nil? - tagging.destroy - print 'D' - next - end - create_label_from_tagging(tagging) - end - end - - def down - Label.destroy_all - LabelLink.destroy_all - end - - private - - def create_label_from_tagging(tagging) - target = tagging.taggable - label_name = tagging.tag.name - # '?', '&' and ',' are no longer allowed in label names so we remove them - label_name.tr!('?&,', '') - label = target.project.labels.find_or_create_by(title: label_name, color: Label::DEFAULT_COLOR) - - if label.valid? && LabelLink.create(label: label, target: target) - print '.' - else - print 'F' - end - end -end diff --git a/db/migrate/20140730111702_add_index_to_labels.rb b/db/migrate/20140730111702_add_index_to_labels.rb deleted file mode 100644 index 494241c873cbd742272c3b94e3b192da94d3ce60..0000000000000000000000000000000000000000 --- a/db/migrate/20140730111702_add_index_to_labels.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddIndexToLabels < ActiveRecord::Migration - def change - add_index "labels", :project_id - add_index "label_links", :label_id - add_index "label_links", [:target_id, :target_type] - end -end diff --git a/db/migrate/20140903115954_migrate_to_new_shell.rb b/db/migrate/20140903115954_migrate_to_new_shell.rb deleted file mode 100644 index 2d83210951332d9c16ce253831dd5ef596dba6d8..0000000000000000000000000000000000000000 --- a/db/migrate/20140903115954_migrate_to_new_shell.rb +++ /dev/null @@ -1,10 +0,0 @@ -class MigrateToNewShell < ActiveRecord::Migration - def change - gitlab_shell_path = Gitlab.config.gitlab_shell.path - if system("#{gitlab_shell_path}/bin/create-hooks") - puts 'Repositories updated with new hooks' - else - raise 'Failed to rewrite gitlab-shell hooks in repositories' - end - end -end diff --git a/db/migrate/20140907220153_serialize_service_properties.rb b/db/migrate/20140907220153_serialize_service_properties.rb deleted file mode 100644 index d45a10465be7ad8ef62a537b8c2128d67c91eb7b..0000000000000000000000000000000000000000 --- a/db/migrate/20140907220153_serialize_service_properties.rb +++ /dev/null @@ -1,42 +0,0 @@ -class SerializeServiceProperties < ActiveRecord::Migration - def change - unless column_exists?(:services, :properties) - add_column :services, :properties, :text - end - - Service.reset_column_information - - associations = - { - AssemblaService: [:token, :subdomain], - CampfireService: [:token, :subdomain, :room], - EmailsOnPushService: [:recipients], - FlowdockService: [:token], - GemnasiumService: [:api_key, :token], - GitlabCiService: [:token, :project_url], - HipchatService: [:token, :room], - PivotaltrackerService: [:token], - SlackService: [:subdomain, :token, :room], - JenkinsService: [:project_url], - JiraService: [:project_url, :username, :password, - :api_version, :jira_issue_transition_id], - } - - Service.find_each(batch_size: 500).each do |service| - associations[service.type.to_sym].each do |attribute| - service.send("#{attribute}=", service.attributes[attribute.to_s]) - end - - service.save(validate: false) - end - - if column_exists?(:services, :project_url) - remove_column :services, :project_url, :string - remove_column :services, :subdomain, :string - remove_column :services, :room, :string - remove_column :services, :recipients, :text - remove_column :services, :api_key, :string - remove_column :services, :token, :string - end - end -end diff --git a/db/migrate/20140914113604_add_members_table.rb b/db/migrate/20140914113604_add_members_table.rb deleted file mode 100644 index d311f3033ee65d75156391b27cfecffb6a02785e..0000000000000000000000000000000000000000 --- a/db/migrate/20140914113604_add_members_table.rb +++ /dev/null @@ -1,19 +0,0 @@ -class AddMembersTable < ActiveRecord::Migration - def change - create_table :members do |t| - t.integer :access_level, null: false - t.integer :source_id, null: false - t.string :source_type, null: false - t.integer :user_id, null: false - t.integer :notification_level, null: false - t.string :type - - t.timestamps - end - - add_index :members, :type - add_index :members, :user_id - add_index :members, :access_level - add_index :members, [:source_id, :source_type] - end -end diff --git a/db/migrate/20140914145549_migrate_to_new_members_model.rb b/db/migrate/20140914145549_migrate_to_new_members_model.rb deleted file mode 100644 index 2a5a49c724a8c555e05a3a15511d2235e17f7bef..0000000000000000000000000000000000000000 --- a/db/migrate/20140914145549_migrate_to_new_members_model.rb +++ /dev/null @@ -1,11 +0,0 @@ -class MigrateToNewMembersModel < ActiveRecord::Migration - def up - execute "INSERT INTO members ( user_id, source_id, source_type, access_level, notification_level, type ) SELECT user_id, group_id, 'Namespace', group_access, notification_level, 'GroupMember' FROM users_groups" - execute "INSERT INTO members ( user_id, source_id, source_type, access_level, notification_level, type ) SELECT user_id, project_id, 'Project', project_access, notification_level, 'ProjectMember' FROM users_projects" - end - - def down - Member.delete_all - end -end - diff --git a/db/migrate/20140914173417_remove_old_member_tables.rb b/db/migrate/20140914173417_remove_old_member_tables.rb deleted file mode 100644 index 408b9551dbb466bdbf30284b741b8dfe2ed805c2..0000000000000000000000000000000000000000 --- a/db/migrate/20140914173417_remove_old_member_tables.rb +++ /dev/null @@ -1,26 +0,0 @@ -class RemoveOldMemberTables < ActiveRecord::Migration - def up - drop_table :users_groups - drop_table :users_projects - end - - def down - create_table :users_groups do |t| - t.integer :group_access, null: false - t.integer :group_id, null: false - t.integer :user_id, null: false - t.integer :notification_level, null: false, default: 3 - - t.timestamps - end - - create_table :users_projects do |t| - t.integer :project_access, null: false - t.integer :project_id, null: false - t.integer :user_id, null: false - t.integer :notification_level, null: false, default: 3 - - t.timestamps - end - end -end diff --git a/db/migrate/20141006143943_move_slack_service_to_webhook.rb b/db/migrate/20141006143943_move_slack_service_to_webhook.rb deleted file mode 100644 index 5836cd6b8dba3fdfa9b7b0c782e915864c06e1ca..0000000000000000000000000000000000000000 --- a/db/migrate/20141006143943_move_slack_service_to_webhook.rb +++ /dev/null @@ -1,17 +0,0 @@ -class MoveSlackServiceToWebhook < ActiveRecord::Migration - def change - SlackService.all.each do |slack_service| - if ["token", "subdomain"].all? { |property| slack_service.properties.key? property } - token = slack_service.properties['token'] - subdomain = slack_service.properties['subdomain'] - webhook = "https://#{subdomain}.slack.com/services/hooks/incoming-webhook?token=#{token}" - slack_service.properties['webhook'] = webhook - slack_service.properties.delete('token') - slack_service.properties.delete('subdomain') - # Room is configured on the Slack side - slack_service.properties.delete('room') - slack_service.save(validate: false) - end - end - end -end diff --git a/db/migrate/20141007100818_add_visibility_level_to_snippet.rb b/db/migrate/20141007100818_add_visibility_level_to_snippet.rb deleted file mode 100644 index 7f125acb5d1d2803e15ab6f88533796373749518..0000000000000000000000000000000000000000 --- a/db/migrate/20141007100818_add_visibility_level_to_snippet.rb +++ /dev/null @@ -1,21 +0,0 @@ -class AddVisibilityLevelToSnippet < ActiveRecord::Migration - def up - add_column :snippets, :visibility_level, :integer, :default => 0, :null => false - - Snippet.where(private: true).update_all(visibility_level: Gitlab::VisibilityLevel::PRIVATE) - Snippet.where(private: false).update_all(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - - add_index :snippets, :visibility_level - - remove_column :snippets, :private - end - - def down - add_column :snippets, :private, :boolean, :default => false, :null => false - - Snippet.where(visibility_level: Gitlab::VisibilityLevel::INTERNAL).update_all(private: false) - Snippet.where(visibility_level: Gitlab::VisibilityLevel::PRIVATE).update_all(private: true) - - remove_column :snippets, :visibility_level - end -end diff --git a/db/migrate/20141121133009_add_timestamps_to_members.rb b/db/migrate/20141121133009_add_timestamps_to_members.rb deleted file mode 100644 index ef6d4dedf32c95a69f85cc471def6bd66b392f36..0000000000000000000000000000000000000000 --- a/db/migrate/20141121133009_add_timestamps_to_members.rb +++ /dev/null @@ -1,15 +0,0 @@ -# In 20140914145549_migrate_to_new_members_model.rb we forgot to set the -# created_at and updated_at times for new records in the 'members' table. This -# became a problem after commit c8e78d972a5a628870eefca0f2ccea0199c55bda which -# was added in GitLab 7.5. With this migration we ensure that all rows in -# 'members' have at least some created_at and updated_at timestamp. -class AddTimestampsToMembers < ActiveRecord::Migration - def up - execute "UPDATE members SET created_at = NOW() WHERE created_at is NULL" - execute "UPDATE members SET updated_at = NOW() WHERE updated_at is NULL" - end - - def down - # no change - end -end diff --git a/db/migrate/20141121161704_add_identity_table.rb b/db/migrate/20141121161704_add_identity_table.rb deleted file mode 100644 index a85b0426cec8b36e762a94767ff302876501296b..0000000000000000000000000000000000000000 --- a/db/migrate/20141121161704_add_identity_table.rb +++ /dev/null @@ -1,46 +0,0 @@ -class AddIdentityTable < ActiveRecord::Migration - def up - create_table :identities do |t| - t.string :extern_uid - t.string :provider - t.references :user - end - - add_index :identities, :user_id - - execute < 2 - end -end diff --git a/db/migrate/20150205211843_add_timestamps_to_identities.rb b/db/migrate/20150205211843_add_timestamps_to_identities.rb deleted file mode 100644 index 77cddbfec3b2b9af2c44df09031a193e13ee46ca..0000000000000000000000000000000000000000 --- a/db/migrate/20150205211843_add_timestamps_to_identities.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTimestampsToIdentities < ActiveRecord::Migration - def change - add_timestamps(:identities) - end -end diff --git a/db/migrate/20150206181414_add_index_to_created_at.rb b/db/migrate/20150206181414_add_index_to_created_at.rb deleted file mode 100644 index fc624fca60dd8acc3c3960832cfccd84a53cf289..0000000000000000000000000000000000000000 --- a/db/migrate/20150206181414_add_index_to_created_at.rb +++ /dev/null @@ -1,16 +0,0 @@ -class AddIndexToCreatedAt < ActiveRecord::Migration - def change - add_index "users", [:created_at, :id] - add_index "members", [:created_at, :id] - add_index "projects", [:created_at, :id] - add_index "issues", [:created_at, :id] - add_index "merge_requests", [:created_at, :id] - add_index "milestones", [:created_at, :id] - add_index "namespaces", [:created_at, :id] - add_index "notes", [:created_at, :id] - add_index "identities", [:created_at, :id] - add_index "keys", [:created_at, :id] - add_index "web_hooks", [:created_at, :id] - add_index "snippets", [:created_at, :id] - end -end diff --git a/db/migrate/20150206222854_add_notification_email_to_user.rb b/db/migrate/20150206222854_add_notification_email_to_user.rb deleted file mode 100644 index ab80f7e582f3022d75e3c0e6f734f44bc73293a2..0000000000000000000000000000000000000000 --- a/db/migrate/20150206222854_add_notification_email_to_user.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddNotificationEmailToUser < ActiveRecord::Migration - def up - add_column :users, :notification_email, :string - - execute "UPDATE users SET notification_email = email" - end - - def down - remove_column :users, :notification_email - end -end diff --git a/db/migrate/20150209222013_add_missing_index.rb b/db/migrate/20150209222013_add_missing_index.rb deleted file mode 100644 index a816c2e9e8ca11e9754b371e809339b19138544d..0000000000000000000000000000000000000000 --- a/db/migrate/20150209222013_add_missing_index.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddMissingIndex < ActiveRecord::Migration - def change - add_index "services", [:created_at, :id] - end -end diff --git a/db/migrate/20150211172122_add_template_to_service.rb b/db/migrate/20150211172122_add_template_to_service.rb deleted file mode 100644 index b1bfbc45ee9ab36c5f48a69d16e868e6f3c7ca56..0000000000000000000000000000000000000000 --- a/db/migrate/20150211172122_add_template_to_service.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTemplateToService < ActiveRecord::Migration - def change - add_column :services, :template, :boolean, default: false - end -end diff --git a/db/migrate/20150211174341_allow_null_in_services_project_id.rb b/db/migrate/20150211174341_allow_null_in_services_project_id.rb deleted file mode 100644 index 68f0281279159537ca2cbb2990e967fd3d3d7277..0000000000000000000000000000000000000000 --- a/db/migrate/20150211174341_allow_null_in_services_project_id.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AllowNullInServicesProjectId < ActiveRecord::Migration - def change - change_column :services, :project_id, :integer, null: true - end -end diff --git a/db/migrate/20150213104043_add_twitter_sharing_enabled_to_application_settings.rb b/db/migrate/20150213104043_add_twitter_sharing_enabled_to_application_settings.rb deleted file mode 100644 index a0439172391f07f26e4f08ee1e4ff027ad40d571..0000000000000000000000000000000000000000 --- a/db/migrate/20150213104043_add_twitter_sharing_enabled_to_application_settings.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTwitterSharingEnabledToApplicationSettings < ActiveRecord::Migration - def change - add_column :application_settings, :twitter_sharing_enabled, :boolean, default: true - end -end diff --git a/db/migrate/20150213114800_add_hide_no_password_to_user.rb b/db/migrate/20150213114800_add_hide_no_password_to_user.rb deleted file mode 100644 index 685f08442762183f53bad4ec097324aec9b04971..0000000000000000000000000000000000000000 --- a/db/migrate/20150213114800_add_hide_no_password_to_user.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddHideNoPasswordToUser < ActiveRecord::Migration - def change - add_column :users, :hide_no_password, :boolean, default: false - end -end diff --git a/db/migrate/20150213121042_add_password_automatically_set_to_user.rb b/db/migrate/20150213121042_add_password_automatically_set_to_user.rb deleted file mode 100644 index c3c7c1ffc77d8f10e4c1e6fd3b2f2018c1c31d8d..0000000000000000000000000000000000000000 --- a/db/migrate/20150213121042_add_password_automatically_set_to_user.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPasswordAutomaticallySetToUser < ActiveRecord::Migration - def change - add_column :users, :password_automatically_set, :boolean, default: false - end -end diff --git a/db/migrate/20150217123345_add_bitbucket_access_token_and_secret_to_user.rb b/db/migrate/20150217123345_add_bitbucket_access_token_and_secret_to_user.rb deleted file mode 100644 index 23ac1b399ec4007dc91ff6ab893015979ecbb1cb..0000000000000000000000000000000000000000 --- a/db/migrate/20150217123345_add_bitbucket_access_token_and_secret_to_user.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddBitbucketAccessTokenAndSecretToUser < ActiveRecord::Migration - def change - add_column :users, :bitbucket_access_token, :string - add_column :users, :bitbucket_access_token_secret, :string - end -end diff --git a/db/migrate/20150219004514_add_events_to_services.rb b/db/migrate/20150219004514_add_events_to_services.rb deleted file mode 100644 index cf73a0174f4f6d7992729bc79b08f7952285aedb..0000000000000000000000000000000000000000 --- a/db/migrate/20150219004514_add_events_to_services.rb +++ /dev/null @@ -1,8 +0,0 @@ -class AddEventsToServices < ActiveRecord::Migration - def change - add_column :services, :push_events, :boolean, :default => true - add_column :services, :issues_events, :boolean, :default => true - add_column :services, :merge_requests_events, :boolean, :default => true - add_column :services, :tag_push_events, :boolean, :default => true - end -end diff --git a/db/migrate/20150223022001_set_missing_last_activity_at.rb b/db/migrate/20150223022001_set_missing_last_activity_at.rb deleted file mode 100644 index 3f6d4d83474f639fa4fdfa102576051b020c76f4..0000000000000000000000000000000000000000 --- a/db/migrate/20150223022001_set_missing_last_activity_at.rb +++ /dev/null @@ -1,8 +0,0 @@ -class SetMissingLastActivityAt < ActiveRecord::Migration - def up - execute "UPDATE projects SET last_activity_at = updated_at WHERE last_activity_at IS NULL" - end - - def down - end -end diff --git a/db/migrate/20150225065047_add_note_events_to_services.rb b/db/migrate/20150225065047_add_note_events_to_services.rb deleted file mode 100644 index d54ba9e482f846fb8170227a0fd80197e9438b0f..0000000000000000000000000000000000000000 --- a/db/migrate/20150225065047_add_note_events_to_services.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddNoteEventsToServices < ActiveRecord::Migration - def change - add_column :services, :note_events, :boolean, default: true, null: false - end -end diff --git a/db/migrate/20150301014758_add_restricted_visibility_levels_to_application_settings.rb b/db/migrate/20150301014758_add_restricted_visibility_levels_to_application_settings.rb deleted file mode 100644 index 494c3033bfff79c57151b773fe72abb2a8195860..0000000000000000000000000000000000000000 --- a/db/migrate/20150301014758_add_restricted_visibility_levels_to_application_settings.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddRestrictedVisibilityLevelsToApplicationSettings < ActiveRecord::Migration - def change - add_column :application_settings, :restricted_visibility_levels, :text - end -end diff --git a/db/migrate/20150306023106_fix_namespace_duplication.rb b/db/migrate/20150306023106_fix_namespace_duplication.rb deleted file mode 100644 index 334e5574559e361a717b5d6ad6951ce0efd554d2..0000000000000000000000000000000000000000 --- a/db/migrate/20150306023106_fix_namespace_duplication.rb +++ /dev/null @@ -1,21 +0,0 @@ -class FixNamespaceDuplication < ActiveRecord::Migration - def up - #fixes path duplication - select_all('SELECT MAX(id) max, COUNT(id) cnt, path FROM namespaces GROUP BY path HAVING COUNT(id) > 1').each do |nms| - bad_nms_ids = select_all("SELECT id FROM namespaces WHERE path = '#{nms['path']}' AND id <> #{nms['max']}").map{|x| x["id"]} - execute("UPDATE projects SET namespace_id = #{nms["max"]} WHERE namespace_id IN(#{bad_nms_ids.join(', ')})") - execute("DELETE FROM namespaces WHERE id IN(#{bad_nms_ids.join(', ')})") - end - - #fixes name duplication - select_all('SELECT MAX(id) max, COUNT(id) cnt, name FROM namespaces GROUP BY name HAVING COUNT(id) > 1').each do |nms| - bad_nms_ids = select_all("SELECT id FROM namespaces WHERE name = '#{nms['name']}' AND id <> #{nms['max']}").map{|x| x["id"]} - execute("UPDATE projects SET namespace_id = #{nms["max"]} WHERE namespace_id IN(#{bad_nms_ids.join(', ')})") - execute("DELETE FROM namespaces WHERE id IN(#{bad_nms_ids.join(', ')})") - end - end - - def down - # not implemented - end -end diff --git a/db/migrate/20150306023112_add_unique_index_to_namespace.rb b/db/migrate/20150306023112_add_unique_index_to_namespace.rb deleted file mode 100644 index 6472138e3eff92e0b9fda45f40644bab4acc441b..0000000000000000000000000000000000000000 --- a/db/migrate/20150306023112_add_unique_index_to_namespace.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddUniqueIndexToNamespace < ActiveRecord::Migration - def change - remove_index :namespaces, column: :name if index_exists?(:namespaces, :name) - remove_index :namespaces, column: :path if index_exists?(:namespaces, :path) - - add_index :namespaces, :name, unique: true - add_index :namespaces, :path, unique: true - end -end diff --git a/db/migrate/20150313012111_create_subscriptions_table.rb b/db/migrate/20150313012111_create_subscriptions_table.rb deleted file mode 100644 index a1d4d9dedc57048388dfe1a3109c7fc6c09ace7e..0000000000000000000000000000000000000000 --- a/db/migrate/20150313012111_create_subscriptions_table.rb +++ /dev/null @@ -1,16 +0,0 @@ -class CreateSubscriptionsTable < ActiveRecord::Migration - def change - create_table :subscriptions do |t| - t.integer :user_id - t.references :subscribable, polymorphic: true - t.boolean :subscribed - - t.timestamps - end - - add_index :subscriptions, - [:subscribable_id, :subscribable_type, :user_id], - unique: true, - name: 'subscriptions_user_id_and_ref_fields' - end -end diff --git a/db/migrate/20150320234437_add_location_to_user.rb b/db/migrate/20150320234437_add_location_to_user.rb deleted file mode 100644 index 32731d37d7558c4a01a3577372ea9ea8463f11d2..0000000000000000000000000000000000000000 --- a/db/migrate/20150320234437_add_location_to_user.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddLocationToUser < ActiveRecord::Migration - def change - add_column :users, :location, :string - end -end diff --git a/db/migrate/20150324155957_set_incorrect_assignee_id_to_null.rb b/db/migrate/20150324155957_set_incorrect_assignee_id_to_null.rb deleted file mode 100644 index 42dc8173e46ee315b46d68c8a2ed3a040427956e..0000000000000000000000000000000000000000 --- a/db/migrate/20150324155957_set_incorrect_assignee_id_to_null.rb +++ /dev/null @@ -1,6 +0,0 @@ -class SetIncorrectAssigneeIdToNull < ActiveRecord::Migration - def up - execute "UPDATE issues SET assignee_id = NULL WHERE assignee_id = -1" - execute "UPDATE merge_requests SET assignee_id = NULL WHERE assignee_id = -1" - end -end diff --git a/db/migrate/20150327122227_add_public_to_key.rb b/db/migrate/20150327122227_add_public_to_key.rb deleted file mode 100644 index 6ffbf4cda193e41c239c0cbeb7d995f624ffc1b7..0000000000000000000000000000000000000000 --- a/db/migrate/20150327122227_add_public_to_key.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPublicToKey < ActiveRecord::Migration - def change - add_column :keys, :public, :boolean, default: false, null: false - end -end diff --git a/db/migrate/20150327150017_add_import_data_to_project.rb b/db/migrate/20150327150017_add_import_data_to_project.rb deleted file mode 100644 index 12c00339eec41f067b0e254788c0f7045c8a79c2..0000000000000000000000000000000000000000 --- a/db/migrate/20150327150017_add_import_data_to_project.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddImportDataToProject < ActiveRecord::Migration - def change - add_column :projects, :import_data, :text - end -end diff --git a/db/migrate/20150328132231_add_max_attachment_size_to_application_settings.rb b/db/migrate/20150328132231_add_max_attachment_size_to_application_settings.rb deleted file mode 100644 index 1d161674a9a90a5a285e0545dd557d756a3872e8..0000000000000000000000000000000000000000 --- a/db/migrate/20150328132231_add_max_attachment_size_to_application_settings.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddMaxAttachmentSizeToApplicationSettings < ActiveRecord::Migration - def change - add_column :application_settings, :max_attachment_size, :integer, default: 10, null: false - end -end diff --git a/db/migrate/20150406133311_add_invite_data_to_member.rb b/db/migrate/20150406133311_add_invite_data_to_member.rb deleted file mode 100644 index 3452fd45c4febf179fce98a517dd2aa7188d64f1..0000000000000000000000000000000000000000 --- a/db/migrate/20150406133311_add_invite_data_to_member.rb +++ /dev/null @@ -1,12 +0,0 @@ -class AddInviteDataToMember < ActiveRecord::Migration - def change - add_column :members, :created_by_id, :integer - add_column :members, :invite_email, :string - add_column :members, :invite_token, :string - add_column :members, :invite_accepted_at, :datetime - - change_column :members, :user_id, :integer, null: true - - add_index :members, :invite_token, unique: true - end -end diff --git a/db/migrate/20150411000035_fix_identities.rb b/db/migrate/20150411000035_fix_identities.rb deleted file mode 100644 index d9051f9fffdc0004da8de01fc026b13a2e25529b..0000000000000000000000000000000000000000 --- a/db/migrate/20150411000035_fix_identities.rb +++ /dev/null @@ -1,45 +0,0 @@ -class FixIdentities < ActiveRecord::Migration - def up - # Up until now, legacy 'ldap' references in the database were charitably - # interpreted to point to the first LDAP server specified in the GitLab - # configuration. So if the database said 'provider: ldap' but the first - # LDAP server was called 'ldapmain', then we would try to interpret - # 'provider: ldap' as if it said 'provider: ldapmain'. This migration (and - # accompanying changes in the GitLab LDAP code) get rid of this complicated - # behavior. Any database references to 'provider: ldap' get rewritten to - # whatever the code would have interpreted it as, i.e. as a reference to - # the first LDAP server specified in gitlab.yml / gitlab.rb. - new_provider = if Gitlab.config.ldap.enabled - first_ldap_server = Gitlab.config.ldap.servers.values.first - first_ldap_server['provider_name'] - else - 'ldapmain' - end - - # Delete duplicate identities - # We use a sort of self-join to find rows in identities which match on - # user_id but where one has provider 'ldap'. We delete the duplicate row - # with provider 'ldap'. - delete_statement = '' - case adapter_name.downcase - when /^mysql/ - delete_statement << 'DELETE FROM id1 USING identities AS id1, identities AS id2' - when 'postgresql' - delete_statement << 'DELETE FROM identities AS id1 USING identities AS id2' - else - raise "Unknown DB adapter: #{adapter_name}" - end - delete_statement << " WHERE id1.user_id = id2.user_id AND id1.provider = 'ldap' AND id2.provider = '#{new_provider}'" - execute delete_statement - - # Update legacy identities - execute "UPDATE identities SET provider = '#{new_provider}' WHERE provider = 'ldap'" - - if table_exists?('ldap_group_links') - execute "UPDATE ldap_group_links SET provider = '#{new_provider}' WHERE provider IS NULL OR provider = 'ldap'" - end - end - - def down - end -end diff --git a/db/migrate/20150411180045_rename_buildbox_service.rb b/db/migrate/20150411180045_rename_buildbox_service.rb deleted file mode 100644 index 5a0b5d07e50f91ee6c23ae445affafd56c7232ef..0000000000000000000000000000000000000000 --- a/db/migrate/20150411180045_rename_buildbox_service.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RenameBuildboxService < ActiveRecord::Migration - def up - execute "UPDATE services SET type = 'BuildkiteService' WHERE type = 'BuildboxService';" - end - - def down - execute "UPDATE services SET type = 'BuildboxService' WHERE type = 'BuildkiteService';" - end -end diff --git a/db/migrate/20150413192223_add_public_email_to_users.rb b/db/migrate/20150413192223_add_public_email_to_users.rb deleted file mode 100644 index 700e9f343a68f418c88aeab75c90535e3677949f..0000000000000000000000000000000000000000 --- a/db/migrate/20150413192223_add_public_email_to_users.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPublicEmailToUsers < ActiveRecord::Migration - def change - add_column :users, :public_email, :string, default: "", null: false - end -end diff --git a/db/migrate/limits_to_mysql.rb b/db/migrate/limits_to_mysql.rb deleted file mode 100644 index 2b7afae6d7cb3f73197f2c6d9549ba216429af82..0000000000000000000000000000000000000000 --- a/db/migrate/limits_to_mysql.rb +++ /dev/null @@ -1,10 +0,0 @@ -class LimitsToMysql < ActiveRecord::Migration - def up - return unless ActiveRecord::Base.configurations[Rails.env]['adapter'] =~ /^mysql/ - - change_column :merge_request_diffs, :st_commits, :text, limit: 2147483647 - change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647 - change_column :snippets, :content, :text, limit: 2147483647 - change_column :notes, :st_diff, :text, limit: 2147483647 - end -end diff --git a/db/seeds.rb b/db/seeds.rb deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/doc/README.md b/doc/README.md deleted file mode 100644 index 4e00dceac2bffbd6c67319da54921dcce81d524d..0000000000000000000000000000000000000000 --- a/doc/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Documentation - -## User documentation - -- [API](api/README.md) Automate GitLab via a simple and powerful API. -- [Markdown](markdown/markdown.md) GitLab's advanced formatting system. -- [Permissions](permissions/permissions.md) Learn what each role in a project (guest/reporter/developer/master/owner) can do. -- [Project Services](project_services/project_services.md) Integrate a project with external services, such as CI and chat. -- [Public access](public_access/public_access.md) Learn how you can allow public and internal access to projects. -- [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects. -- [Web hooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project. -- [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN. -- [GitLab as OAuth2 authentication service provider](integration/oauth_provider.md). It allows you to login to other applications from GitLab. - -## Administrator documentation - -- [Install](install/README.md) Requirements, directory structures and installation from source. -- [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, LDAP and Twitter. -- [Raketasks](raketasks/README.md) Backups, maintenance, automatic web hook setup and the importing of projects. -- [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when web hooks aren't enough. -- [System hooks](system_hooks/system_hooks.md) Notifications when users, projects and keys are changed. -- [Security](security/README.md) Learn what you can do to further secure your GitLab instance. -- [Update](update/README.md) Update guides to upgrade your installation. -- [Welcome message](customization/welcome_message.md) Add a custom welcome message to the sign-in page. -- [Issue closing](customization/issue_closing.md) Customize how to close an issue from commit messages. -- [Libravatar](customization/libravatar.md) Use Libravatar for user avatars. -- [Operations](operations/README.md) Keeping GitLab up and running -- [Log system](logs/logs.md) Log system - -## Contributor documentation - -- [Development](development/README.md) Explains the architecture and the guidelines for shell commands. -- [Legal](legal/README.md) Contributor license agreements. -- [Release](release/README.md) How to make the monthly and security releases. diff --git a/doc/api/README.md b/doc/api/README.md deleted file mode 100644 index dec530d0b812022be099d3023f279de0b3e850dc..0000000000000000000000000000000000000000 --- a/doc/api/README.md +++ /dev/null @@ -1,209 +0,0 @@ -# GitLab API - -## Resources - -- [Users](users.md) -- [Session](session.md) -- [Projects](projects.md) -- [Project Snippets](project_snippets.md) -- [Repositories](repositories.md) -- [Repository Files](repository_files.md) -- [Commits](commits.md) -- [Branches](branches.md) -- [Merge Requests](merge_requests.md) -- [Issues](issues.md) -- [Labels](labels.md) -- [Milestones](milestones.md) -- [Notes](notes.md) (comments) -- [Deploy Keys](deploy_keys.md) -- [System Hooks](system_hooks.md) -- [Groups](groups.md) - -## Clients - -Find API Clients for GitLab [on our website](https://about.gitlab.com/applications/#api-clients). -You can use [GitLab as an OAuth2 client](oauth2.md) to make API calls. - -## Introduction - -All API requests require authentication. You need to pass a `private_token` parameter by URL or header. If passed as header, the header name must be "PRIVATE-TOKEN" (capital and with dash instead of underscore). You can find or reset your private token in your profile. - -If no, or an invalid, `private_token` is provided then an error message will be returned with status code 401: - -```json -{ - "message": "401 Unauthorized" -} -``` - -API requests should be prefixed with `api` and the API version. The API version is defined in `lib/api.rb`. - -Example of a valid API request: - -``` -GET http://example.com/api/v3/projects?private_token=QVy1PB7sTxfy4pqfZM1U -``` - -Example for a valid API request using curl and authentication via header: - -``` -curl --header "PRIVATE-TOKEN: QVy1PB7sTxfy4pqfZM1U" "http://example.com/api/v3/projects" -``` - -The API uses JSON to serialize data. You don't need to specify `.json` at the end of API URL. - -## Authentication with OAuth2 token - -Instead of the private_token you can transmit the OAuth2 access token as a header or as a parameter. - -### OAuth2 token (as a parameter) - -``` -curl https://localhost:3000/api/v3/user?access_token=OAUTH-TOKEN -``` - -### OAuth2 token (as a header) - -``` -curl -H "Authorization: Bearer OAUTH-TOKEN" https://localhost:3000/api/v3/user -``` - -Read more about [GitLab as an OAuth2 client](oauth2.md). - -## Status codes - -The API is designed to return different status codes according to context and action. In this way if a request results in an error the caller is able to get insight into what went wrong, e.g. status code `400 Bad Request` is returned if a required attribute is missing from the request. The following list gives an overview of how the API functions generally behave. - -API request types: - -- `GET` requests access one or more resources and return the result as JSON -- `POST` requests return `201 Created` if the resource is successfully created and return the newly created resource as JSON -- `GET`, `PUT` and `DELETE` return `200 OK` if the resource is accessed, modified or deleted successfully, the (modified) result is returned as JSON -- `DELETE` requests are designed to be idempotent, meaning a request a resource still returns `200 OK` even it was deleted before or is not available. The reasoning behind it is the user is not really interested if the resource existed before or not. - -The following list shows the possible return codes for API requests. - -Return values: - -- `200 OK` - The `GET`, `PUT` or `DELETE` request was successful, the resource(s) itself is returned as JSON -- `201 Created` - The `POST` request was successful and the resource is returned as JSON -- `400 Bad Request` - A required attribute of the API request is missing, e.g. the title of an issue is not given -- `401 Unauthorized` - The user is not authenticated, a valid user token is necessary, see above -- `403 Forbidden` - The request is not allowed, e.g. the user is not allowed to delete a project -- `404 Not Found` - A resource could not be accessed, e.g. an ID for a resource could not be found -- `405 Method Not Allowed` - The request is not supported -- `409 Conflict` - A conflicting resource already exists, e.g. creating a project with a name that already exists -- `422 Unprocessable` - The entity could not be processed -- `500 Server Error` - While handling the request something went wrong on the server side - -## Sudo - -All API requests support performing an api call as if you were another user, if your private token is for an administration account. You need to pass `sudo` parameter by URL or header with an id or username of the user you want to perform the operation as. If passed as header, the header name must be "SUDO" (capitals). - -If a non administrative `private_token` is provided then an error message will be returned with status code 403: - -```json -{ - "message": "403 Forbidden: Must be admin to use sudo" -} -``` - -If the sudo user id or username cannot be found then an error message will be returned with status code 404: - -```json -{ - "message": "404 Not Found: No user id or username for: " -} -``` - -Example of a valid API with sudo request: - -``` -GET http://example.com/api/v3/projects?private_token=QVy1PB7sTxfy4pqfZM1U&sudo=username -``` - -``` -GET http://example.com/api/v3/projects?private_token=QVy1PB7sTxfy4pqfZM1U&sudo=23 -``` - -Example for a valid API request with sudo using curl and authentication via header: - -``` -curl --header "PRIVATE-TOKEN: QVy1PB7sTxfy4pqfZM1U" --header "SUDO: username" "http://example.com/api/v3/projects" -``` - -``` -curl --header "PRIVATE-TOKEN: QVy1PB7sTxfy4pqfZM1U" --header "SUDO: 23" "http://example.com/api/v3/projects" -``` - -## Pagination - -When listing resources you can pass the following parameters: - -- `page` (default: `1`) - page number -- `per_page` (default: `20`, max: `100`) - number of items to list per page - -[Link headers](http://www.w3.org/wiki/LinkHeader) are send back with each response. These have `rel` prev/next/first/last and contain the relevant URL. Please use these instead of generating your own URLs. - -## id vs iid - -When you work with API you may notice two similar fields in api entities: id and iid. The main difference between them is scope. Example: - -Issue: - - id: 46 - iid: 5 - -- id - is unique across all issues. It's used for any api call. -- iid - is unique only in scope of a single project. When you browse issues or merge requests with Web UI, you see iid. - -So if you want to get issue with api you use `http://host/api/v3/.../issues/:id.json`. But when you want to create a link to web page - use `http:://host/project/issues/:iid.json` - -## Data validation and error reporting - -When working with the API you may encounter validation errors. In such case, the API will answer with an HTTP `400` status. -Such errors appear in two cases: - -* A required attribute of the API request is missing, e.g. the title of an issue is not given -* An attribute did not pass the validation, e.g. user bio is too long - -When an attribute is missing, you will get something like: - - HTTP/1.1 400 Bad Request - Content-Type: application/json - - { - "message":"400 (Bad request) \"title\" not given" - } - -When a validation error occurs, error messages will be different. They will hold all details of validation errors: - - HTTP/1.1 400 Bad Request - Content-Type: application/json - - { - "message": { - "bio": [ - "is too long (maximum is 255 characters)" - ] - } - } - -This makes error messages more machine-readable. The format can be described as follow: - - { - "message": { - "": [ - "", - "", - ... - ], - "": { - "": [ - "", - "", - ... - ], - } - } - } diff --git a/doc/api/branches.md b/doc/api/branches.md deleted file mode 100644 index 6a9c10c85206d9ee3f0820332abcbd45782c5a60..0000000000000000000000000000000000000000 --- a/doc/api/branches.md +++ /dev/null @@ -1,192 +0,0 @@ -# Branches - -## List repository branches - -Get a list of repository branches from a project, sorted by name alphabetically. - -``` -GET /projects/:id/repository/branches -``` - -Parameters: - -- `id` (required) - The ID of a project - -```json -[ - { - "commit": { - "author_email": "john@example.com", - "author_name": "John Smith", - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00", - "committer_email": "john@example.com", - "committer_name": "John Smith", - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "message": "add projects API", - "parent_ids": [ - "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - ] - }, - "name": "master", - "protected": true - } -] -``` - -## Get single repository branch - -Get a single project repository branch. - -``` -GET /projects/:id/repository/branches/:branch -``` - -Parameters: - -- `id` (required) - The ID of a project -- `branch` (required) - The name of the branch - -```json -{ - "commit": { - "author_email": "john@example.com", - "author_name": "John Smith", - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00", - "committer_email": "john@example.com", - "committer_name": "John Smith", - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "message": "add projects API", - "parent_ids": [ - "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - ] - }, - "name": "master", - "protected": true -} -``` - -## Protect repository branch - -Protects a single project repository branch. This is an idempotent function, protecting an already -protected repository branch still returns a `200 OK` status code. - -``` -PUT /projects/:id/repository/branches/:branch/protect -``` - -Parameters: - -- `id` (required) - The ID of a project -- `branch` (required) - The name of the branch - -```json -{ - "commit": { - "author_email": "john@example.com", - "author_name": "John Smith", - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00", - "committer_email": "john@example.com", - "committer_name": "John Smith", - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "message": "add projects API", - "parent_ids": [ - "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - ] - }, - "name": "master", - "protected": true -} -``` - -## Unprotect repository branch - -Unprotects a single project repository branch. This is an idempotent function, unprotecting an already -unprotected repository branch still returns a `200 OK` status code. - -``` -PUT /projects/:id/repository/branches/:branch/unprotect -``` - -Parameters: - -- `id` (required) - The ID of a project -- `branch` (required) - The name of the branch - -```json -{ - "commit": { - "author_email": "john@example.com", - "author_name": "John Smith", - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00", - "committer_email": "john@example.com", - "committer_name": "John Smith", - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "message": "add projects API", - "parent_ids": [ - "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - ] - }, - "name": "master", - "protected": false -} -``` - -## Create repository branch - -``` -POST /projects/:id/repository/branches -``` - -Parameters: - -- `id` (required) - The ID of a project -- `branch_name` (required) - The name of the branch -- `ref` (required) - Create branch from commit SHA or existing branch - -```json -{ - "commit": { - "author_email": "john@example.com", - "author_name": "John Smith", - "authored_date": "2012-06-27T05:51:39-07:00", - "committed_date": "2012-06-28T03:44:20-07:00", - "committer_email": "john@example.com", - "committer_name": "John Smith", - "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", - "message": "add projects API", - "parent_ids": [ - "4ad91d3c1144c406e50c7b33bae684bd6837faf8" - ] - }, - "name": "master", - "protected": false -} -``` - -It return 200 if succeed or 400 if failed with error message explaining reason. - -## Delete repository branch - -``` -DELETE /projects/:id/repository/branches/:branch -``` - -Parameters: - -- `id` (required) - The ID of a project -- `branch` (required) - The name of the branch - -It return 200 if succeed, 404 if the branch to be deleted does not exist -or 400 for other reasons. In case of an error, an explaining message is provided. - -Success response: - -```json -{ - "branch_name": "my-removed-branch" -} -``` diff --git a/doc/api/commits.md b/doc/api/commits.md deleted file mode 100644 index eb8d6a43592a0f2210317c59719fac951e9ca36a..0000000000000000000000000000000000000000 --- a/doc/api/commits.md +++ /dev/null @@ -1,158 +0,0 @@ -# Commits API - -## List repository commits - -Get a list of repository commits in a project. - -``` -GET /projects/:id/repository/commits -``` - -Parameters: - -- `id` (required) - The ID of a project -- `ref_name` (optional) - The name of a repository branch or tag or if not given the default branch - -```json -[ - { - "id": "ed899a2f4b50b4370feeea94676502b42383c746", - "short_id": "ed899a2f4b5", - "title": "Replace sanitize with escape once", - "author_name": "Dmitriy Zaporozhets", - "author_email": "dzaporozhets@sphereconsultinginc.com", - "created_at": "2012-09-20T11:50:22+03:00", - "message": "Replace sanitize with escape once" - }, - { - "id": "6104942438c14ec7bd21c6cd5bd995272b3faff6", - "short_id": "6104942438c", - "title": "Sanitize for network graph", - "author_name": "randx", - "author_email": "dmitriy.zaporozhets@gmail.com", - "created_at": "2012-09-20T09:06:12+03:00", - "message": "Sanitize for network graph" - } -] -``` - -## Get a single commit - -Get a specific commit identified by the commit hash or name of a branch or tag. - -``` -GET /projects/:id/repository/commits/:sha -``` - -Parameters: - -- `id` (required) - The ID of a project -- `sha` (required) - The commit hash or name of a repository branch or tag - -```json -{ - "id": "6104942438c14ec7bd21c6cd5bd995272b3faff6", - "short_id": "6104942438c", - "title": "Sanitize for network graph", - "author_name": "randx", - "author_email": "dmitriy.zaporozhets@gmail.com", - "created_at": "2012-09-20T09:06:12+03:00", - "message": "Sanitize for network graph", - "committed_date": "2012-09-20T09:06:12+03:00", - "authored_date": "2012-09-20T09:06:12+03:00", - "parent_ids": [ - "ae1d9fb46aa2b07ee9836d49862ec4e2c46fbbba" - ] -} -``` - -## Get the diff of a commit - -Get the diff of a commit in a project. - -``` -GET /projects/:id/repository/commits/:sha/diff -``` - -Parameters: - -- `id` (required) - The ID of a project -- `sha` (required) - The name of a repository branch or tag or if not given the default branch - -```json -[ - { - "diff": "--- a/doc/update/5.4-to-6.0.md\n+++ b/doc/update/5.4-to-6.0.md\n@@ -71,6 +71,8 @@\n sudo -u git -H bundle exec rake migrate_keys RAILS_ENV=production\n sudo -u git -H bundle exec rake migrate_inline_notes RAILS_ENV=production\n \n+sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production\n+\n ```\n \n ### 6. Update config files", - "new_path": "doc/update/5.4-to-6.0.md", - "old_path": "doc/update/5.4-to-6.0.md", - "a_mode": null, - "b_mode": "100644", - "new_file": false, - "renamed_file": false, - "deleted_file": false - } -] -``` - -## Get the comments of a commit - -Get the comments of a commit in a project. - -``` -GET /projects/:id/repository/commits/:sha/comments -``` - -Parameters: - -- `id` (required) - The ID of a project -- `sha` (required) - The name of a repository branch or tag or if not given the default branch - -```json -[ - { - "note": "this code is really nice", - "author": { - "id": 11, - "username": "admin", - "email": "admin@local.host", - "name": "Administrator", - "state": "active", - "created_at": "2014-03-06T08:17:35.000Z" - } - } -] -``` - -## Post comment to commit - -Adds a comment to a commit. Optionally you can post comments on a specific line of a commit. Therefor both `path`, `line_new` and `line_old` are required. - -``` -POST /projects/:id/repository/commits/:sha/comments -``` - -Parameters: - -- `id` (required) - The ID of a project -- `sha` (required) - The name of a repository branch or tag or if not given the default branch -- `note` (required) - Text of comment -- `path` (optional) - The file path -- `line` (optional) - The line number -- `line_type` (optional) - The line type (new or old) - -```json -{ - "author": { - "id": 1, - "username": "admin", - "email": "admin@local.host", - "name": "Administrator", - "blocked": false, - "created_at": "2012-04-29T08:46:00Z" - }, - "note": "text1", - "path": "example.rb", - "line": 5, - "line_type": "new" -} -``` diff --git a/doc/api/deploy_key_multiple_projects.md b/doc/api/deploy_key_multiple_projects.md deleted file mode 100644 index 1a5a458905e061112acd95d20f0b1876ad88ecb3..0000000000000000000000000000000000000000 --- a/doc/api/deploy_key_multiple_projects.md +++ /dev/null @@ -1,25 +0,0 @@ -# Adding deploy keys to multiple projects - -If you want to easily add the same deploy key to multiple projects in the same group, this can be achieved quite easily with the API. - -First, find the ID of the projects you're interested in, by either listing all projects: - -``` -curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/projects -``` - -Or finding the id of a group and then listing all projects in that group: - -``` -curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/groups - -# For group 1234: -curl --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/groups/1234 -``` - -With those IDs, add the same deploy key to all: -``` -for project_id in 321 456 987; do - curl -X POST --data '{"title": "my key", "key": "ssh-rsa AAAA..."}' --header 'PRIVATE-TOKEN: abcdef' https://gitlab.com/api/v3/projects/${project_id}/keys -done -``` diff --git a/doc/api/deploy_keys.md b/doc/api/deploy_keys.md deleted file mode 100644 index e4492fc609c11faf8d77104f54750ee605f68b67..0000000000000000000000000000000000000000 --- a/doc/api/deploy_keys.md +++ /dev/null @@ -1,80 +0,0 @@ -# Deploy Keys - -## List deploy keys - -Get a list of a project's deploy keys. - -``` -GET /projects/:id/keys -``` - -Parameters: - -- `id` (required) - The ID of the project - -```json -[ - { - "id": 1, - "title": "Public key", - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", - "created_at": "2013-10-02T10:12:29Z" - }, - { - "id": 3, - "title": "Another Public key", - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", - "created_at": "2013-10-02T11:12:29Z" - } -] -``` - -## Single deploy key - -Get a single key. - -``` -GET /projects/:id/keys/:key_id -``` - -Parameters: - -- `id` (required) - The ID of the project -- `key_id` (required) - The ID of the deploy key - -```json -{ - "id": 1, - "title": "Public key", - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", - "created_at": "2013-10-02T10:12:29Z" -} -``` - -## Add deploy key - -Creates a new deploy key for a project. -If deploy key already exists in another project - it will be joined to project but only if original one was is accessible by same user - -``` -POST /projects/:id/keys -``` - -Parameters: - -- `id` (required) - The ID of the project -- `title` (required) - New deploy key's title -- `key` (required) - New deploy key - -## Delete deploy key - -Delete a deploy key from a project - -``` -DELETE /projects/:id/keys/:key_id -``` - -Parameters: - -- `id` (required) - The ID of the project -- `key_id` (required) - The ID of the deploy key diff --git a/doc/api/groups.md b/doc/api/groups.md deleted file mode 100644 index b5a4b05ccaf2cd0cdd9487d8f2d6be698e6d84c8..0000000000000000000000000000000000000000 --- a/doc/api/groups.md +++ /dev/null @@ -1,178 +0,0 @@ -# Groups - -## List project groups - -Get a list of groups. (As user: my groups, as admin: all groups) - -``` -GET /groups -``` - -```json -[ - { - "id": 1, - "name": "Foobar Group", - "path": "foo-bar", - "description": "An interesting group" - } -] -``` - -You can search for groups by name or path, see below. - -## Details of a group - -Get all details of a group. - -``` -GET /groups/:id -``` - -Parameters: - -- `id` (required) - The ID or path of a group - -## New group - -Creates a new project group. Available only for admin. - -``` -POST /groups -``` - -Parameters: - -- `name` (required) - The name of the group -- `path` (required) - The path of the group -- `description` (optional) - The group's description - -## Transfer project to group - -Transfer a project to the Group namespace. Available only for admin - -``` -POST /groups/:id/projects/:project_id -``` - -Parameters: - -- `id` (required) - The ID or path of a group -- `project_id` (required) - The ID of a project - -## Remove group - -Removes group with all projects inside. - -``` -DELETE /groups/:id -``` - -Parameters: - -- `id` (required) - The ID or path of a user group - -## Search for group - -Get all groups that match your string in their name or path. - -``` -GET /groups?search=foobar -``` - -```json -[ - { - "id": 1, - "name": "Foobar Group", - "path": "foo-bar", - "description": "An interesting group" - } -] -``` - -## Group members - -**Group access levels** - -The group access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized: - -``` -GUEST = 10 -REPORTER = 20 -DEVELOPER = 30 -MASTER = 40 -OWNER = 50 -``` - -### List group members - -Get a list of group members viewable by the authenticated user. - -``` -GET /groups/:id/members -``` - -```json -[ - { - "id": 1, - "username": "raymond_smith", - "email": "ray@smith.org", - "name": "Raymond Smith", - "state": "active", - "created_at": "2012-10-22T14:13:35Z", - "access_level": 30 - }, - { - "id": 2, - "username": "john_doe", - "email": "joh@doe.org", - "name": "John Doe", - "state": "active", - "created_at": "2012-10-22T14:13:35Z", - "access_level": 30 - } -] -``` - -### Add group member - -Adds a user to the list of group members. - -``` -POST /groups/:id/members -``` - -Parameters: - -- `id` (required) - The ID or path of a group -- `user_id` (required) - The ID of a user to add -- `access_level` (required) - Project access level - -### Edit group team member - -Updates a group team member to a specified access level. - -``` -PUT /groups/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID of a group -- `user_id` (required) - The ID of a group member -- `access_level` (required) - Project access level - -### Remove user team member - -Removes user from user team. - -``` -DELETE /groups/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID or path of a user group -- `user_id` (required) - The ID of a group member diff --git a/doc/api/issues.md b/doc/api/issues.md deleted file mode 100644 index a7dd8b74c35a3f6799c732663d2798ead68db0ba..0000000000000000000000000000000000000000 --- a/doc/api/issues.md +++ /dev/null @@ -1,224 +0,0 @@ -# Issues - -## List issues - -Get all issues created by authenticated user. This function takes pagination parameters -`page` and `per_page` to restrict the list of issues. - -``` -GET /issues -GET /issues?state=opened -GET /issues?state=closed -GET /issues?labels=foo -GET /issues?labels=foo,bar -GET /issues?labels=foo,bar&state=opened -``` - -Parameters: - -- `state` (optional) - Return `all` issues or just those that are `opened` or `closed` -- `labels` (optional) - Comma-separated list of label names -- `order_by` (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` -- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` - -```json -[ - { - "id": 43, - "iid": 3, - "project_id": 8, - "title": "4xx/5xx pages", - "description": "", - "labels": [], - "milestone": null, - "assignee": null, - "author": { - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "state": "active", - "created_at": "2012-05-23T08:00:58Z" - }, - "state": "closed", - "updated_at": "2012-07-02T17:53:12Z", - "created_at": "2012-07-02T17:53:12Z" - }, - { - "id": 42, - "iid": 4, - "project_id": 8, - "title": "Add user settings", - "description": "", - "labels": [ - "feature" - ], - "milestone": { - "id": 1, - "title": "v1.0", - "description": "", - "due_date": "2012-07-20", - "state": "reopened", - "updated_at": "2012-07-04T13:42:48Z", - "created_at": "2012-07-04T13:42:48Z" - }, - "assignee": { - "id": 2, - "username": "jack_smith", - "email": "jack@example.com", - "name": "Jack Smith", - "state": "active", - "created_at": "2012-05-23T08:01:01Z" - }, - "author": { - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "state": "active", - "created_at": "2012-05-23T08:00:58Z" - }, - "state": "opened", - "updated_at": "2012-07-12T13:43:19Z", - "created_at": "2012-06-28T12:58:06Z" - } -] -``` - -## List project issues - -Get a list of project issues. This function accepts pagination parameters `page` and `per_page` -to return the list of project issues. - -``` -GET /projects/:id/issues -GET /projects/:id/issues?state=opened -GET /projects/:id/issues?state=closed -GET /projects/:id/issues?labels=foo -GET /projects/:id/issues?labels=foo,bar -GET /projects/:id/issues?labels=foo,bar&state=opened -GET /projects/:id/issues?milestone=1.0.0 -GET /projects/:id/issues?milestone=1.0.0&state=opened -``` - -Parameters: - -- `id` (required) - The ID of a project -- `state` (optional) - Return `all` issues or just those that are `opened` or `closed` -- `labels` (optional) - Comma-separated list of label names -- `milestone` (optional) - Milestone title -- `order_by` (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` -- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` - -## Single issue - -Gets a single project issue. - -``` -GET /projects/:id/issues/:issue_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `issue_id` (required) - The ID of a project issue - -```json -{ - "id": 42, - "iid": 3, - "project_id": 8, - "title": "Add user settings", - "description": "", - "labels": [ - "feature" - ], - "milestone": { - "id": 1, - "title": "v1.0", - "description": "", - "due_date": "2012-07-20", - "state": "closed", - "updated_at": "2012-07-04T13:42:48Z", - "created_at": "2012-07-04T13:42:48Z" - }, - "assignee": { - "id": 2, - "username": "jack_smith", - "email": "jack@example.com", - "name": "Jack Smith", - "state": "active", - "created_at": "2012-05-23T08:01:01Z" - }, - "author": { - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "state": "active", - "created_at": "2012-05-23T08:00:58Z" - }, - "state": "opened", - "updated_at": "2012-07-12T13:43:19Z", - "created_at": "2012-06-28T12:58:06Z" -} -``` - -## New issue - -Creates a new project issue. - -``` -POST /projects/:id/issues -``` - -Parameters: - -- `id` (required) - The ID of a project -- `title` (required) - The title of an issue -- `description` (optional) - The description of an issue -- `assignee_id` (optional) - The ID of a user to assign issue -- `milestone_id` (optional) - The ID of a milestone to assign issue -- `labels` (optional) - Comma-separated label names for an issue - -If the operation is successful, 200 and the newly created issue is returned. -If an error occurs, an error number and a message explaining the reason is returned. - -## Edit issue - -Updates an existing project issue. This function is also used to mark an issue as closed. - -``` -PUT /projects/:id/issues/:issue_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `issue_id` (required) - The ID of a project's issue -- `title` (optional) - The title of an issue -- `description` (optional) - The description of an issue -- `assignee_id` (optional) - The ID of a user to assign issue -- `milestone_id` (optional) - The ID of a milestone to assign issue -- `labels` (optional) - Comma-separated label names for an issue -- `state_event` (optional) - The state event of an issue ('close' to close issue and 'reopen' to reopen it) - -If the operation is successful, 200 and the updated issue is returned. -If an error occurs, an error number and a message explaining the reason is returned. - -## Delete existing issue (**Deprecated**) - -The function is deprecated and returns a `405 Method Not Allowed` error if called. An issue gets now closed and is done by calling `PUT /projects/:id/issues/:issue_id` with parameter `state_event` set to `close`. - -``` -DELETE /projects/:id/issues/:issue_id -``` - -Parameters: - -- `id` (required) - The project ID -- `issue_id` (required) - The ID of the issue - -## Comments on issues - -Comments are done via the notes resource. diff --git a/doc/api/labels.md b/doc/api/labels.md deleted file mode 100644 index de41f35d284ee86d45d3ae62483fea6da3e500ec..0000000000000000000000000000000000000000 --- a/doc/api/labels.md +++ /dev/null @@ -1,84 +0,0 @@ -# Labels - -## List labels - -Get all labels for given project. - -``` -GET /projects/:id/labels -``` - -```json -[ - { - "name": "Awesome", - "color": "#DD10AA" - }, - { - "name": "Documentation", - "color": "#1E80DD" - }, - { - "name": "Feature", - "color": "#11FF22" - }, - { - "name": "Bug", - "color": "#EE1122" - } -] -``` - -## Create a new label - -Creates a new label for given repository with given name and color. - -``` -POST /projects/:id/labels -``` - -Parameters: - -- `id` (required) - The ID of a project -- `name` (required) - The name of the label -- `color` (required) - Color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) - -It returns 200 and the newly created label, if the operation succeeds. -If the label already exists, 409 and an error message is returned. -If label parameters are invalid, 400 and an explaining error message is returned. - -## Delete a label - -Deletes a label given by its name. - -``` -DELETE /projects/:id/labels -``` - -- `id` (required) - The ID of a project -- `name` (required) - The name of the label to be deleted - -It returns 200 if the label successfully was deleted, 400 for wrong parameters -and 404 if the label does not exist. -In case of an error, additionally an error message is returned. - -## Edit an existing label - -Updates an existing label with new name or now color. At least one parameter -is required, to update the label. - -``` -PUT /projects/:id/labels -``` - -Parameters: - -- `id` (required) - The ID of a project -- `name` (required) - The name of the existing label -- `new_name` (optional) - The new name of the label -- `color` (optional) - New color of the label given in 6-digit hex notation with leading '#' sign (e.g. #FFAABB) - -On success, this method returns 200 with the updated label. -If required parameters are missing or parameters are invalid, 400 is returned. -If the label to be updated is missing, 404 is returned. -In case of an error, additionally an error message is returned. diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md deleted file mode 100644 index 6a272539e45fb7db43877b74652fe24dbffcb0ed..0000000000000000000000000000000000000000 --- a/doc/api/merge_requests.md +++ /dev/null @@ -1,393 +0,0 @@ -# Merge requests - -## List merge requests - -Get all merge requests for this project. -The `state` parameter can be used to get only merge requests with a given state (`opened`, `closed`, or `merged`) or all of them (`all`). -The pagination parameters `page` and `per_page` can be used to restrict the list of merge requests. - -``` -GET /projects/:id/merge_requests -GET /projects/:id/merge_requests?state=opened -GET /projects/:id/merge_requests?state=all -``` - -Parameters: - -- `id` (required) - The ID of a project -- `state` (optional) - Return `all` requests or just those that are `merged`, `opened` or `closed` -- `order_by` (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` -- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` - -```json -[ - { - "id": 1, - "iid": 1, - "target_branch": "master", - "source_branch": "test1", - "project_id": 3, - "title": "test1", - "state": "opened", - "upvotes": 0, - "downvotes": 0, - "author": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - }, - "assignee": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - }, - "description":"fixed login page css paddings" - } -] -``` - -## Get single MR - -Shows information about a single merge request. - -``` -GET /projects/:id/merge_request/:merge_request_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of MR - -```json -{ - "id": 1, - "iid": 1, - "target_branch": "master", - "source_branch": "test1", - "project_id": 3, - "title": "test1", - "state": "merged", - "upvotes": 0, - "downvotes": 0, - "author": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - }, - "assignee": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - }, - "description":"fixed login page css paddings" -} -``` - -## Get single MR changes - -Shows information about the merge request including its files and changes - -``` -GET /projects/:id/merge_request/:merge_request_id/changes -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of MR - -```json -{ - "id": 21, - "iid": 1, - "project_id": 4, - "title": "Blanditiis beatae suscipit hic assumenda et molestias nisi asperiores repellat et.", - "description": "Qui voluptatibus placeat ipsa alias quasi. Deleniti rem ut sint. Optio velit qui distinctio.", - "state": "reopened", - "created_at": "2015-02-02T19:49:39.159Z", - "updated_at": "2015-02-02T20:08:49.959Z", - "target_branch": "secret_token", - "source_branch": "version-1-9", - "upvotes": 0, - "downvotes": 0, - "author": { - "name": "Chad Hamill", - "username": "jarrett", - "id": 5, - "state": "active", - "avatar_url": "http://www.gravatar.com/avatar/b95567800f828948baf5f4160ebb2473?s=40&d=identicon" - }, - "assignee": { - "name": "Administrator", - "username": "root", - "id": 1, - "state": "active", - "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon" - }, - "source_project_id": 4, - "target_project_id": 4, - "labels": [ ], - "milestone": { - "id": 5, - "iid": 1, - "project_id": 4, - "title": "v2.0", - "description": "Assumenda aut placeat expedita exercitationem labore sunt enim earum.", - "state": "closed", - "created_at": "2015-02-02T19:49:26.013Z", - "updated_at": "2015-02-02T19:49:26.013Z", - "due_date": null - }, - "files": [ - { - "old_path": "VERSION", - "new_path": "VERSION", - "a_mode": "100644", - "b_mode": "100644", - "diff": "--- a/VERSION\ +++ b/VERSION\ @@ -1 +1 @@\ -1.9.7\ +1.9.8", - "new_file": false, - "renamed_file": false, - "deleted_file": false - } - ] -} -``` - -## Create MR - -Creates a new merge request. - -``` -POST /projects/:id/merge_requests -``` - -Parameters: - -- `id` (required) - The ID of a project -- `source_branch` (required) - The source branch -- `target_branch` (required) - The target branch -- `assignee_id` (optional) - Assignee user ID -- `title` (required) - Title of MR -- `description` (optional) - Description of MR -- `target_project_id` (optional) - The target project (numeric id) - -```json -{ - "id": 1, - "target_branch": "master", - "source_branch": "test1", - "project_id": 3, - "title": "test1", - "state": "opened", - "upvotes": 0, - "downvotes": 0, - "author": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - }, - "assignee": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - }, - "description":"fixed login page css paddings" -} -``` - -If the operation is successful, 200 and the newly created merge request is returned. -If an error occurs, an error number and a message explaining the reason is returned. - -## Update MR - -Updates an existing merge request. You can change branches, title, or even close the MR. - -``` -PUT /projects/:id/merge_request/:merge_request_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - ID of MR -- `source_branch` - The source branch -- `target_branch` - The target branch -- `assignee_id` - Assignee user ID -- `title` - Title of MR -- `description` - Description of MR -- `state_event` - New state (close|reopen|merge) - -```json -{ - "id": 1, - "target_branch": "master", - "source_branch": "test1", - "project_id": 3, - "title": "test1", - "description": "description1", - "state": "opened", - "upvotes": 0, - "downvotes": 0, - "author": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - }, - "assignee": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - } -} -``` - -If the operation is successful, 200 and the updated merge request is returned. -If an error occurs, an error number and a message explaining the reason is returned. - -## Accept MR - -Merge changes submitted with MR using this API. - -If merge success you get `200 OK`. - -If it has some conflicts and can not be merged - you get 405 and error message 'Branch cannot be merged' - -If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed' - -If you don't have permissions to accept this merge request - you'll get a 401 - -``` -PUT /projects/:id/merge_request/:merge_request_id/merge -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - ID of MR -- `merge_commit_message` (optional) - Custom merge commit message - -```json -{ - "id": 1, - "target_branch": "master", - "source_branch": "test1", - "project_id": 3, - "title": "test1", - "state": "merged", - "upvotes": 0, - "downvotes": 0, - "author": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - }, - "assignee": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2012-04-29T08:46:00Z" - } -} -``` - -## Post comment to MR - -Adds a comment to a merge request. - -``` -POST /projects/:id/merge_request/:merge_request_id/comments -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - ID of merge request -- `note` (required) - Text of comment - -```json -{ - "author": { - "id": 1, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "blocked": false, - "created_at": "2012-04-29T08:46:00Z" - }, - "note": "text1" -} -``` - -## Get the comments on a MR - -Gets all the comments associated with a merge request. - -``` -GET /projects/:id/merge_request/:merge_request_id/comments -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - ID of merge request - -```json -[ - { - "note": "this is the 1st comment on the 2merge merge request", - "author": { - "id": 11, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2014-03-06T08:17:35.000Z" - } - }, - { - "note": "Status changed to closed", - "author": { - "id": 11, - "username": "admin", - "email": "admin@example.com", - "name": "Administrator", - "state": "active", - "created_at": "2014-03-06T08:17:35.000Z" - } - } -] -``` - -## Comments on issues - -Comments are done via the notes resource. diff --git a/doc/api/milestones.md b/doc/api/milestones.md deleted file mode 100644 index d48b3bcce8aa3fe83ea93db902957e3ac9056d65..0000000000000000000000000000000000000000 --- a/doc/api/milestones.md +++ /dev/null @@ -1,87 +0,0 @@ -# Milestones - -## List project milestones - -Returns a list of project milestones. - -``` -GET /projects/:id/milestones -``` - -```json -[ - { - "id": 12, - "iid": 3, - "project_id": 16, - "title": "10.0", - "description": "Version", - "due_date": "2013-11-29", - "state": "active", - "updated_at": "2013-10-02T09:24:18Z", - "created_at": "2013-10-02T09:24:18Z" - } -] -``` - -Parameters: - -- `id` (required) - The ID of a project - -## Get single milestone - -Gets a single project milestone. - -``` -GET /projects/:id/milestones/:milestone_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `milestone_id` (required) - The ID of a project milestone - -## Create new milestone - -Creates a new project milestone. - -``` -POST /projects/:id/milestones -``` - -Parameters: - -- `id` (required) - The ID of a project -- `title` (required) - The title of an milestone -- `description` (optional) - The description of the milestone -- `due_date` (optional) - The due date of the milestone - -## Edit milestone - -Updates an existing project milestone. - -``` -PUT /projects/:id/milestones/:milestone_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `milestone_id` (required) - The ID of a project milestone -- `title` (optional) - The title of a milestone -- `description` (optional) - The description of a milestone -- `due_date` (optional) - The due date of the milestone -- `state_event` (optional) - The state event of the milestone (close|activate) - -## Get all issues assigned to a single milestone - -Gets all issues assigned to a single project milestone. - -``` -GET /projects/:id/milestones/:milestone_id/issues -``` - -Parameters: - -- `id` (required) - The ID of a project -- `milestone_id` (required) - The ID of a project milestone diff --git a/doc/api/notes.md b/doc/api/notes.md deleted file mode 100644 index ee2f9fa0eac7192ebe6f8d7b4fa7cc46d039d254..0000000000000000000000000000000000000000 --- a/doc/api/notes.md +++ /dev/null @@ -1,246 +0,0 @@ -# Notes - -Notes are comments on snippets, issues or merge requests. - -## Issues - -### List project issue notes - -Gets a list of all notes for a single issue. - -``` -GET /projects/:id/issues/:issue_id/notes -``` - -Parameters: - -- `id` (required) - The ID of a project -- `issue_id` (required) - The ID of an issue - -```json -[ - { - "id": 302, - "body": "Status changed to closed", - "attachment": null, - "author": { - "id": 1, - "username": "pipin", - "email": "admin@example.com", - "name": "Pip", - "state": "active", - "created_at": "2013-09-30T13:46:01Z" - }, - "created_at": "2013-10-02T09:22:45Z" - }, - { - "id": 305, - "body": "Text of the comment\r\n", - "attachment": null, - "author": { - "id": 1, - "username": "pipin", - "email": "admin@example.com", - "name": "Pip", - "state": "active", - "created_at": "2013-09-30T13:46:01Z" - }, - "created_at": "2013-10-02T09:56:03Z" - } -] -``` - -### Get single issue note - -Returns a single note for a specific project issue - -``` -GET /projects/:id/issues/:issue_id/notes/:note_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `issue_id` (required) - The ID of a project issue -- `note_id` (required) - The ID of an issue note - -### Create new issue note - -Creates a new note to a single project issue. - -``` -POST /projects/:id/issues/:issue_id/notes -``` - -Parameters: - -- `id` (required) - The ID of a project -- `issue_id` (required) - The ID of an issue -- `body` (required) - The content of a note - -### Modify existing issue note - -Modify existing note of an issue. - -``` -PUT /projects/:id/issues/:issue_id/notes/:note_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `issue_id` (required) - The ID of an issue -- `note_id` (required) - The ID of a note -- `body` (required) - The content of a note - -## Snippets - -### List all snippet notes - -Gets a list of all notes for a single snippet. Snippet notes are comments users can post to a snippet. - -``` -GET /projects/:id/snippets/:snippet_id/notes -``` - -Parameters: - -- `id` (required) - The ID of a project -- `snippet_id` (required) - The ID of a project snippet - -### Get single snippet note - -Returns a single note for a given snippet. - -``` -GET /projects/:id/snippets/:snippet_id/notes/:note_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `snippet_id` (required) - The ID of a project snippet -- `note_id` (required) - The ID of an snippet note - -```json -{ - "id": 52, - "title": "Snippet", - "file_name": "snippet.rb", - "author": { - "id": 1, - "username": "pipin", - "email": "admin@example.com", - "name": "Pip", - "state": "active", - "created_at": "2013-09-30T13:46:01Z" - }, - "expires_at": null, - "updated_at": "2013-10-02T07:34:20Z", - "created_at": "2013-10-02T07:34:20Z" -} -``` - -### Create new snippet note - -Creates a new note for a single snippet. Snippet notes are comments users can post to a snippet. - -``` -POST /projects/:id/snippets/:snippet_id/notes -``` - -Parameters: - -- `id` (required) - The ID of a project -- `snippet_id` (required) - The ID of a snippet -- `body` (required) - The content of a note - -### Modify existing snippet note - -Modify existing note of a snippet. - -``` -PUT /projects/:id/snippets/:snippet_id/notes/:note_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `snippet_id` (required) - The ID of a snippet -- `note_id` (required) - The ID of a note -- `body` (required) - The content of a note - -## Merge Requests - -### List all merge request notes - -Gets a list of all notes for a single merge request. - -``` -GET /projects/:id/merge_requests/:merge_request_id/notes -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of a project merge request - -### Get single merge request note - -Returns a single note for a given merge request. - -``` -GET /projects/:id/merge_requests/:merge_request_id/notes/:note_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of a project merge request -- `note_id` (required) - The ID of a merge request note - -```json -{ - "id": 301, - "body": "Comment for MR", - "attachment": null, - "author": { - "id": 1, - "username": "pipin", - "email": "admin@example.com", - "name": "Pip", - "state": "active", - "created_at": "2013-09-30T13:46:01Z" - }, - "created_at": "2013-10-02T08:57:14Z" -} -``` - -### Create new merge request note - -Creates a new note for a single merge request. - -``` -POST /projects/:id/merge_requests/:merge_request_id/notes -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of a merge request -- `body` (required) - The content of a note - -### Modify existing merge request note - -Modify existing note of a merge request. - -``` -PUT /projects/:id/merge_requests/:merge_request_id/notes/:note_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of a merge request -- `note_id` (required) - The ID of a note -- `body` (required) - The content of a note diff --git a/doc/api/oauth2.md b/doc/api/oauth2.md deleted file mode 100644 index d416a826f797f68d6e5324f8a562d85fa4813326..0000000000000000000000000000000000000000 --- a/doc/api/oauth2.md +++ /dev/null @@ -1,102 +0,0 @@ -# GitLab as an OAuth2 client - -This document is about using other OAuth authentication service providers to sign into GitLab. -If you want GitLab to be an OAuth authentication service provider to sign into other services please see the [Oauth2 provider documentation](../integration/oauth_provider.md). - -OAuth2 is a protocol that enables us to authenticate a user without requiring them to give their password. - -Before using the OAuth2 you should create an application in user's account. Each application gets a unique App ID and App Secret parameters. You should not share these. - -This functionality is based on [doorkeeper gem](https://github.com/doorkeeper-gem/doorkeeper) - -## Web Application Flow - -This flow is using for authentication from third-party web sites and is probably used the most. -It basically consists of an exchange of an authorization token for an access token. For more detailed info, check out the [RFC spec here](http://tools.ietf.org/html/rfc6749#section-4.1) - -This flow consists from 3 steps. - -### 1. Registering the client - -Create an application in user's account profile. - -### 2. Requesting authorization - -To request the authorization token, you should visit the `/oauth/authorize` endpoint. You can do that by visiting manually the URL: - -``` -http://localhost:3000/oauth/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&response_type=code -``` - -Where REDIRECT_URI is the URL in your app where users will be sent after authorization. - -### 3. Requesting the access token - -To request the access token, you should use the returned code and exchange it for an access token. To do that you can use any HTTP client. In this case, I used rest-client: - -``` -parameters = 'client_id=APP_ID&client_secret=APP_SECRET&code=RETURNED_CODE&grant_type=AUTHORIZATION_CODE&redirect_uri=REDIRECT_URI' -RestClient.post 'http://localhost:3000/oauth/token', parameters - -# The response will be -{ - "access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54", - "token_type": "bearer", - "expires_in": 7200, - "refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1" -} -``` - -You can now make requests to the API with the access token returned. - -### Use the access token to access the API - -The access token allows you to make requests to the API on a behalf of a user. - -``` -GET https://localhost:3000/api/v3/user?access_token=OAUTH-TOKEN -``` - -Or you can put the token to the Authorization header: - -``` -curl -H "Authorization: Bearer OAUTH-TOKEN" https://localhost:3000/api/v3/user -``` - -## Resource Owner Password Credentials - -In this flow, a token is requested in exchange for the resource owner credentials (username and password). -The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g. the -client is part of the device operating system or a highly privileged application), and when other authorization grant types are not -available (such as an authorization code). - -Even though this grant type requires direct client access to the resource owner credentials, the resource owner credentials are used -for a single request and are exchanged for an access token. This grant type can eliminate the need for the client to store the -resource owner credentials for future use, by exchanging the credentials with a long-lived access token or refresh token. -You can do POST request to `/oauth/token` with parameters: - -``` -{ - "grant_type" : "password", - "username" : "user@example.com", - "password" : "sekret" -} -``` - -Then, you'll receive the access token back in the response: - -``` -{ - "access_token": "1f0af717251950dbd4d73154fdf0a474a5c5119adad999683f5b450c460726aa", - "token_type": "bearer", - "expires_in": 7200 -} -``` - -For testing you can use the oauth2 ruby gem: - -``` -client = OAuth2::Client.new('the_client_id', 'the_client_secret', :site => "http://example.com") -access_token = client.password.get_token('user@example.com', 'sekret') -puts access_token.token -``` diff --git a/doc/api/project_snippets.md b/doc/api/project_snippets.md deleted file mode 100644 index 50e134847c071914a41962f2f7fd7b5671f62919..0000000000000000000000000000000000000000 --- a/doc/api/project_snippets.md +++ /dev/null @@ -1,103 +0,0 @@ -# Project snippets - -## List snippets - -Get a list of project snippets. - -``` -GET /projects/:id/snippets -``` - -Parameters: - -- `id` (required) - The ID of a project - -## Single snippet - -Get a single project snippet. - -``` -GET /projects/:id/snippets/:snippet_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `snippet_id` (required) - The ID of a project's snippet - -```json -{ - "id": 1, - "title": "test", - "file_name": "add.rb", - "author": { - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "state": "active", - "created_at": "2012-05-23T08:00:58Z" - }, - "expires_at": null, - "updated_at": "2012-06-28T10:52:04Z", - "created_at": "2012-06-28T10:52:04Z" -} -``` - -## Create new snippet - -Creates a new project snippet. The user must have permission to create new snippets. - -``` -POST /projects/:id/snippets -``` - -Parameters: - -- `id` (required) - The ID of a project -- `title` (required) - The title of a snippet -- `file_name` (required) - The name of a snippet file -- `code` (required) - The content of a snippet - -## Update snippet - -Updates an existing project snippet. The user must have permission to change an existing snippet. - -``` -PUT /projects/:id/snippets/:snippet_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `snippet_id` (required) - The ID of a project's snippet -- `title` (optional) - The title of a snippet -- `file_name` (optional) - The name of a snippet file -- `code` (optional) - The content of a snippet - -## Delete snippet - -Deletes an existing project snippet. This is an idempotent function and deleting a non-existent -snippet still returns a `200 OK` status code. - -``` -DELETE /projects/:id/snippets/:snippet_id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `snippet_id` (required) - The ID of a project's snippet - -## Snippet content - -Returns the raw project snippet as plain text. - -``` -GET /projects/:id/snippets/:snippet_id/raw -``` - -Parameters: - -- `id` (required) - The ID of a project -- `snippet_id` (required) - The ID of a project's snippet diff --git a/doc/api/projects.md b/doc/api/projects.md deleted file mode 100644 index 971fe96fb8e6381d73282cff5137389ce9af9bc0..0000000000000000000000000000000000000000 --- a/doc/api/projects.md +++ /dev/null @@ -1,713 +0,0 @@ -# Projects - - -### Project visibility level - -Project in GitLab has be either private, internal or public. -You can determine it by `visibility_level` field in project. - -Constants for project visibility levels are next: - -* Private. `visibility_level` is `0`. - Project access must be granted explicitly for each user. - -* Internal. `visibility_level` is `10`. - The project can be cloned by any logged in user. - -* Public. `visibility_level` is `20`. - The project can be cloned without any authentication. - - -## List projects - -Get a list of projects accessible by the authenticated user. - -``` -GET /projects -``` - -Parameters: - -- `archived` (optional) - if passed, limit by archived status -- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at` -- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` -- `search` (optional) - Return list of authorized projects according to a search criteria - -```json -[ - { - "id": 4, - "description": null, - "default_branch": "master", - "public": false, - "visibility_level": 0, - "ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git", - "http_url_to_repo": "http://example.com/diaspora/diaspora-client.git", - "web_url": "http://example.com/diaspora/diaspora-client", - "tag_list": [ - "example", - "disapora client" - ], - "owner": { - "id": 3, - "name": "Diaspora", - "created_at": "2013-09-30T13: 46: 02Z" - }, - "name": "Diaspora Client", - "name_with_namespace": "Diaspora / Diaspora Client", - "path": "diaspora-client", - "path_with_namespace": "diaspora/diaspora-client", - "issues_enabled": true, - "merge_requests_enabled": true, - "wiki_enabled": true, - "snippets_enabled": false, - "created_at": "2013-09-30T13: 46: 02Z", - "last_activity_at": "2013-09-30T13: 46: 02Z", - "creator_id": 3, - "namespace": { - "created_at": "2013-09-30T13: 46: 02Z", - "description": "", - "id": 3, - "name": "Diaspora", - "owner_id": 1, - "path": "diaspora", - "updated_at": "2013-09-30T13: 46: 02Z" - }, - "archived": false, - "avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png" - }, - { - "id": 6, - "description": null, - "default_branch": "master", - "public": false, - "visibility_level": 0, - "ssh_url_to_repo": "git@example.com:brightbox/puppet.git", - "http_url_to_repo": "http://example.com/brightbox/puppet.git", - "web_url": "http://example.com/brightbox/puppet", - "tag_list": [ - "example", - "puppet" - ], - "owner": { - "id": 4, - "name": "Brightbox", - "created_at": "2013-09-30T13:46:02Z" - }, - "name": "Puppet", - "name_with_namespace": "Brightbox / Puppet", - "path": "puppet", - "path_with_namespace": "brightbox/puppet", - "issues_enabled": true, - "merge_requests_enabled": true, - "wiki_enabled": true, - "snippets_enabled": false, - "created_at": "2013-09-30T13:46:02Z", - "last_activity_at": "2013-09-30T13:46:02Z", - "creator_id": 3, - "namespace": { - "created_at": "2013-09-30T13:46:02Z", - "description": "", - "id": 4, - "name": "Brightbox", - "owner_id": 1, - "path": "brightbox", - "updated_at": "2013-09-30T13:46:02Z" - }, - "archived": false, - "avatar_url": null - } -] -``` - -### List owned projects - -Get a list of projects which are owned by the authenticated user. - -``` -GET /projects/owned -``` - -Parameters: - -- `archived` (optional) - if passed, limit by archived status -- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at` -- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` -- `search` (optional) - Return list of authorized projects according to a search criteria - -### List ALL projects - -Get a list of all GitLab projects (admin only). - -``` -GET /projects/all -``` - -Parameters: - -- `archived` (optional) - if passed, limit by archived status -- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at` -- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` -- `search` (optional) - Return list of authorized projects according to a search criteria - -### Get single project - -Get a specific project, identified by project ID or NAMESPACE/PROJECT_NAME, which is owned by the authenticated user. -If using namespaced projects call make sure that the NAMESPACE/PROJECT_NAME is URL-encoded, eg. `/api/v3/projects/diaspora%2Fdiaspora` (where `/` is represented by `%2F`). - -``` -GET /projects/:id -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project - -```json -{ - "id": 3, - "description": null, - "default_branch": "master", - "public": false, - "visibility_level": 0, - "ssh_url_to_repo": "git@example.com:diaspora/diaspora-project-site.git", - "http_url_to_repo": "http://example.com/diaspora/diaspora-project-site.git", - "web_url": "http://example.com/diaspora/diaspora-project-site", - "tag_list": [ - "example", - "disapora project" - ], - "owner": { - "id": 3, - "name": "Diaspora", - "created_at": "2013-09-30T13: 46: 02Z" - }, - "name": "Diaspora Project Site", - "name_with_namespace": "Diaspora / Diaspora Project Site", - "path": "diaspora-project-site", - "path_with_namespace": "diaspora/diaspora-project-site", - "issues_enabled": true, - "merge_requests_enabled": true, - "wiki_enabled": true, - "snippets_enabled": false, - "created_at": "2013-09-30T13: 46: 02Z", - "last_activity_at": "2013-09-30T13: 46: 02Z", - "creator_id": 3, - "namespace": { - "created_at": "2013-09-30T13: 46: 02Z", - "description": "", - "id": 3, - "name": "Diaspora", - "owner_id": 1, - "path": "diaspora", - "updated_at": "2013-09-30T13: 46: 02Z" - }, - "permissions": { - "project_access": { - "access_level": 10, - "notification_level": 3 - }, - "group_access": { - "access_level": 50, - "notification_level": 3 - } - }, - "archived": false, - "avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png" -} -``` - -### Get project events - -Get the events for the specified project. -Sorted from newest to latest - -``` -GET /projects/:id/events -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project - -```json -[ - { - "title": null, - "project_id": 15, - "action_name": "closed", - "target_id": 830, - "target_type": "Issue", - "author_id": 1, - "author_username": "john", - "data": null, - "target_title": "Public project search field" - }, - { - "title": null, - "project_id": 15, - "action_name": "opened", - "target_id": null, - "target_type": null, - "author_id": 1, - "author_username": "john", - "data": { - "before": "50d4420237a9de7be1304607147aec22e4a14af7", - "after": "c5feabde2d8cd023215af4d2ceeb7a64839fc428", - "ref": "refs/heads/master", - "user_id": 1, - "user_name": "Dmitriy Zaporozhets", - "repository": { - "name": "gitlabhq", - "url": "git@dev.gitlab.org:gitlab/gitlabhq.git", - "description": "GitLab: self hosted Git management software. \r\nDistributed under the MIT License.", - "homepage": "https://dev.gitlab.org/gitlab/gitlabhq" - }, - "commits": [ - { - "id": "c5feabde2d8cd023215af4d2ceeb7a64839fc428", - "message": "Add simple search to projects in public area", - "timestamp": "2013-05-13T18:18:08+00:00", - "url": "https://dev.gitlab.org/gitlab/gitlabhq/commit/c5feabde2d8cd023215af4d2ceeb7a64839fc428", - "author": { - "name": "Dmitriy Zaporozhets", - "email": "dmitriy.zaporozhets@gmail.com" - } - } - ], - "total_commits_count": 1 - }, - "target_title": null - }, - { - "title": null, - "project_id": 15, - "action_name": "closed", - "target_id": 840, - "target_type": "Issue", - "author_id": 1, - "author_username": "john", - "data": null, - "target_title": "Finish & merge Code search PR" - } -] -``` - -### Create project - -Creates a new project owned by the authenticated user. - -``` -POST /projects -``` - -Parameters: - -- `name` (required) - new project name -- `path` (optional) - custom repository name for new project. By default generated based on name -- `namespace_id` (optional) - namespace for the new project (defaults to user) -- `description` (optional) - short project description -- `issues_enabled` (optional) -- `merge_requests_enabled` (optional) -- `wiki_enabled` (optional) -- `snippets_enabled` (optional) -- `public` (optional) - if `true` same as setting visibility_level = 20 -- `visibility_level` (optional) -- `import_url` (optional) - -### Create project for user - -Creates a new project owned by the specified user. Available only for admins. - -``` -POST /projects/user/:user_id -``` - -Parameters: - -- `user_id` (required) - user_id of owner -- `name` (required) - new project name -- `description` (optional) - short project description -- `default_branch` (optional) - 'master' by default -- `issues_enabled` (optional) -- `merge_requests_enabled` (optional) -- `wiki_enabled` (optional) -- `snippets_enabled` (optional) -- `public` (optional) - if `true` same as setting visibility_level = 20 -- `visibility_level` (optional) -- `import_url` (optional) - -### Edit project - -Updates an existing project - -``` -PUT /projects/:id -``` - -Parameters: - -- `id` (required) - The ID of a project -- `name` (optional) - project name -- `path` (optional) - repository name for project -- `description` (optional) - short project description -- `default_branch` (optional) -- `issues_enabled` (optional) -- `merge_requests_enabled` (optional) -- `wiki_enabled` (optional) -- `snippets_enabled` (optional) -- `public` (optional) - if `true` same as setting visibility_level = 20 -- `visibility_level` (optional) - -On success, method returns 200 with the updated project. If parameters are -invalid, 400 is returned. - -### Fork project - -Forks a project into the user namespace of the authenticated user. - -``` -POST /projects/fork/:id -``` - -Parameters: - -- `id` (required) - The ID of the project to be forked - -### Remove project - -Removes a project including all associated resources (issues, merge requests etc.) - -``` -DELETE /projects/:id -``` - -Parameters: - -- `id` (required) - The ID of a project - -## Team members - -### List project team members - -Get a list of a project's team members. - -``` -GET /projects/:id/members -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `query` (optional) - Query string to search for members - -### Get project team member - -Gets a project team member. - -``` -GET /projects/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `user_id` (required) - The ID of a user - -```json -{ - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "state": "active", - "created_at": "2012-05-23T08:00:58Z", - "access_level": 40 -} -``` - -### Add project team member - -Adds a user to a project team. This is an idempotent method and can be called multiple times -with the same parameters. Adding team membership to a user that is already a member does not -affect the existing membership. - -``` -POST /projects/:id/members -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `user_id` (required) - The ID of a user to add -- `access_level` (required) - Project access level - -### Edit project team member - -Updates a project team member to a specified access level. - -``` -PUT /projects/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `user_id` (required) - The ID of a team member -- `access_level` (required) - Project access level - -### Remove project team member - -Removes a user from a project team. - -``` -DELETE /projects/:id/members/:user_id -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `user_id` (required) - The ID of a team member - -This method is idempotent and can be called multiple times with the same parameters. -Revoking team membership for a user who is not currently a team member is considered success. -Please note that the returned JSON currently differs slightly. Thus you should not -rely on the returned JSON structure. - -## Hooks - -### List project hooks - -Get a list of project hooks. - -``` -GET /projects/:id/hooks -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project - -### Get project hook - -Get a specific hook for a project. - -``` -GET /projects/:id/hooks/:hook_id -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `hook_id` (required) - The ID of a project hook - -```json -{ - "id": 1, - "url": "http://example.com/hook", - "project_id": 3, - "push_events": "true", - "issues_events": "true", - "merge_requests_events": "true", - "created_at": "2012-10-12T17:04:47Z" -} -``` - -### Add project hook - -Adds a hook to a specified project. - -``` -POST /projects/:id/hooks -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `url` (required) - The hook URL -- `push_events` - Trigger hook on push events -- `issues_events` - Trigger hook on issues events -- `merge_requests_events` - Trigger hook on merge_requests events -- `tag_push_events` - Trigger hook on push_tag events - -### Edit project hook - -Edits a hook for a specified project. - -``` -PUT /projects/:id/hooks/:hook_id -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `hook_id` (required) - The ID of a project hook -- `url` (required) - The hook URL -- `push_events` - Trigger hook on push events -- `issues_events` - Trigger hook on issues events -- `merge_requests_events` - Trigger hook on merge_requests events -- `tag_push_events` - Trigger hook on push_tag events - -### Delete project hook - -Removes a hook from a project. This is an idempotent method and can be called multiple times. -Either the hook is available or not. - -``` -DELETE /projects/:id/hooks/:hook_id -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `hook_id` (required) - The ID of hook to delete - -Note the JSON response differs if the hook is available or not. If the project hook -is available before it is returned in the JSON response or an empty response is returned. - -## Branches - -### List branches - -Lists all branches of a project. - -``` -GET /projects/:id/repository/branches -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project - -```json -[ - { - "name": "async", - "commit": { - "id": "a2b702edecdf41f07b42653eb1abe30ce98b9fca", - "parents": [ - { - "id": "3f94fc7c85061973edc9906ae170cc269b07ca55" - } - ], - "tree": "c68537c6534a02cc2b176ca1549f4ffa190b58ee", - "message": "give Caolan credit where it's due (up top)", - "author": { - "name": "Jeremy Ashkenas", - "email": "jashkenas@example.com" - }, - "committer": { - "name": "Jeremy Ashkenas", - "email": "jashkenas@example.com" - }, - "authored_date": "2010-12-08T21:28:50+00:00", - "committed_date": "2010-12-08T21:28:50+00:00" - }, - "protected": false - }, - { - "name": "gh-pages", - "commit": { - "id": "101c10a60019fe870d21868835f65c25d64968fc", - "parents": [ - { - "id": "9c15d2e26945a665131af5d7b6d30a06ba338aaa" - } - ], - "tree": "fb5cc9d45da3014b17a876ad539976a0fb9b352a", - "message": "Underscore.js 1.5.2", - "author": { - "name": "Jeremy Ashkenas", - "email": "jashkenas@example.com" - }, - "committer": { - "name": "Jeremy Ashkenas", - "email": "jashkenas@example.com" - }, - "authored_date": "2013-09-07T12: 58: 21+00: 00", - "committed_date": "2013-09-07T12: 58: 21+00: 00" - }, - "protected": false - } -] -``` - -### List single branch - -Lists a specific branch of a project. - -``` -GET /projects/:id/repository/branches/:branch -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `branch` (required) - The name of the branch. - -### Protect single branch - -Protects a single branch of a project. - -``` -PUT /projects/:id/repository/branches/:branch/protect -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `branch` (required) - The name of the branch. - -### Unprotect single branch - -Unprotects a single branch of a project. - -``` -PUT /projects/:id/repository/branches/:branch/unprotect -``` - -Parameters: - -- `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project -- `branch` (required) - The name of the branch. - -## Admin fork relation - -Allows modification of the forked relationship between existing projects. Available only for admins. - -### Create a forked from/to relation between existing projects. - -``` -POST /projects/:id/fork/:forked_from_id -``` - -Parameters: - -- `id` (required) - The ID of the project -- `forked_from_id:` (required) - The ID of the project that was forked from - -### Delete an existing forked from relationship - -``` -DELETE /projects/:id/fork -``` - -Parameter: - -- `id` (required) - The ID of the project - -## Search for projects by name - -Search for projects by name which are accessible to the authenticated user. - -``` -GET /projects/search/:query -``` - -Parameters: - -- `query` (required) - A string contained in the project name -- `per_page` (optional) - number of projects to return per page -- `page` (optional) - the page to retrieve -- `order_by` (optional) - Return requests ordered by `id`, `name`, `created_at` or `last_activity_at` fields -- `sort` (optional) - Return requests sorted in `asc` or `desc` order diff --git a/doc/api/repositories.md b/doc/api/repositories.md deleted file mode 100644 index 331674538028b4d4cbc5d85dad52ccce25fad98f..0000000000000000000000000000000000000000 --- a/doc/api/repositories.md +++ /dev/null @@ -1,252 +0,0 @@ -# Repositories - -## List project repository tags - -Get a list of repository tags from a project, sorted by name in reverse alphabetical order. - -``` -GET /projects/:id/repository/tags -``` - -Parameters: - -- `id` (required) - The ID of a project - -```json -[ - { - "commit": { - "author_name": "John Smith", - "author_email": "john@example.com", - "authored_date": "2012-05-28T04:42:42-07:00", - "committed_date": "2012-05-28T04:42:42-07:00", - "committer_name": "Jack Smith", - "committer_email": "jack@example.com", - "id": "2695effb5807a22ff3d138d593fd856244e155e7", - "message": "Initial commit", - "parents_ids": [ - "2a4b78934375d7f53875269ffd4f45fd83a84ebe" - ] - }, - "name": "v1.0.0", - "message": null - } -] -``` - -## Create a new tag - -Creates new tag in the repository that points to the supplied ref. - -``` -POST /projects/:id/repository/tags -``` - -Parameters: - -- `id` (required) - The ID of a project -- `tag_name` (required) - The name of a tag -- `ref` (required) - Create tag using commit SHA, another tag name, or branch name. -- `message` (optional) - Creates annotated tag. - -```json -{ - "commit": { - "author_name": "John Smith", - "author_email": "john@example.com", - "authored_date": "2012-05-28T04:42:42-07:00", - "committed_date": "2012-05-28T04:42:42-07:00", - "committer_name": "Jack Smith", - "committer_email": "jack@example.com", - "id": "2695effb5807a22ff3d138d593fd856244e155e7", - "message": "Initial commit", - "parents_ids": [ - "2a4b78934375d7f53875269ffd4f45fd83a84ebe" - ] - }, - "name": "v1.0.0", - "message": null -} -``` -The message will be `nil` when creating a lightweight tag otherwise -it will contain the annotation. - -It returns 200 if the operation succeed. In case of an error, -405 with an explaining error message is returned. - -## List repository tree - -Get a list of repository files and directories in a project. - -``` -GET /projects/:id/repository/tree -``` - -Parameters: - -- `id` (required) - The ID of a project -- `path` (optional) - The path inside repository. Used to get contend of subdirectories -- `ref_name` (optional) - The name of a repository branch or tag or if not given the default branch - -```json -[ - { - "name": "assets", - "type": "tree", - "mode": "040000", - "id": "6229c43a7e16fcc7e95f923f8ddadb8281d9c6c6" - }, - { - "name": "contexts", - "type": "tree", - "mode": "040000", - "id": "faf1cdf33feadc7973118ca42d35f1e62977e91f" - }, - { - "name": "controllers", - "type": "tree", - "mode": "040000", - "id": "95633e8d258bf3dfba3a5268fb8440d263218d74" - }, - { - "name": "Rakefile", - "type": "blob", - "mode": "100644", - "id": "35b2f05cbb4566b71b34554cf184a9d0bd9d46d6" - }, - { - "name": "VERSION", - "type": "blob", - "mode": "100644", - "id": "803e4a4f3727286c3093c63870c2b6524d30ec4f" - }, - { - "name": "config.ru", - "type": "blob", - "mode": "100644", - "id": "dfd2d862237323aa599be31b473d70a8a817943b" - } -] -``` - -## Raw file content - -Get the raw file contents for a file by commit SHA and path. - -``` -GET /projects/:id/repository/blobs/:sha -``` - -Parameters: - -- `id` (required) - The ID of a project -- `sha` (required) - The commit or branch name -- `filepath` (required) - The path the file - -## Raw blob content - -Get the raw file contents for a blob by blob SHA. - -``` -GET /projects/:id/repository/raw_blobs/:sha -``` - -Parameters: - -- `id` (required) - The ID of a project -- `sha` (required) - The blob SHA - -## Get file archive - -Get an archive of the repository - -``` -GET /projects/:id/repository/archive -``` - -Parameters: - -- `id` (required) - The ID of a project -- `sha` (optional) - The commit SHA to download defaults to the tip of the default branch - -## Compare branches, tags or commits - -``` -GET /projects/:id/repository/compare -``` - -Parameters: - -- `id` (required) - The ID of a project -- `from` (required) - the commit SHA or branch name -- `to` (required) - the commit SHA or branch name - -``` -GET /projects/:id/repository/compare?from=master&to=feature -``` - -Response: - -```json - -{ - "commit": { - "id": "12d65c8dd2b2676fa3ac47d955accc085a37a9c1", - "short_id": "12d65c8dd2b", - "title": "JS fix", - "author_name": "Dmitriy Zaporozhets", - "author_email": "dmitriy.zaporozhets@gmail.com", - "created_at": "2014-02-27T10:27:00+02:00" - }, - "commits": [{ - "id": "12d65c8dd2b2676fa3ac47d955accc085a37a9c1", - "short_id": "12d65c8dd2b", - "title": "JS fix", - "author_name": "Dmitriy Zaporozhets", - "author_email": "dmitriy.zaporozhets@gmail.com", - "created_at": "2014-02-27T10:27:00+02:00" - }], - "diffs": [{ - "old_path": "files/js/application.js", - "new_path": "files/js/application.js", - "a_mode": null, - "b_mode": "100644", - "diff": "--- a/files/js/application.js\n+++ b/files/js/application.js\n@@ -24,8 +24,10 @@\n //= require g.raphael-min\n //= require g.bar-min\n //= require branch-graph\n-//= require highlightjs.min\n-//= require ace/ace\n //= require_tree .\n //= require d3\n //= require underscore\n+\n+function fix() { \n+ alert(\"Fixed\")\n+}", - "new_file": false, - "renamed_file": false, - "deleted_file": false - }], - "compare_timeout": false, - "compare_same_ref": false -} -``` - -## Contributors - -Get repository contributors list - -``` -GET /projects/:id/repository/contributors -``` - -Parameters: - -- `id` (required) - The ID of a project - -Response: - -``` -[{ - "name": "Dmitriy Zaporozhets", - "email": "dmitriy.zaporozhets@gmail.com", - "commits": 117, - "additions": 2097, - "deletions": 517 -}, { - "name": "Jacob Vosmaer", - "email": "contact@jacobvosmaer.nl", - "commits": 33, - "additions": 338, - "deletions": 244 -}] -``` diff --git a/doc/api/repository_files.md b/doc/api/repository_files.md deleted file mode 100644 index 25311b071076454a994eef8a5d1d61d272520dc1..0000000000000000000000000000000000000000 --- a/doc/api/repository_files.md +++ /dev/null @@ -1,109 +0,0 @@ -# Repository files - -**CRUD for repository files** - -**Create, read, update and delete repository files using this API** - -## Get file from repository - -Allows you to receive information about file in repository like name, size, content. Note that file content is Base64 encoded. - -``` -GET /projects/:id/repository/files -``` - -Example response: - -```json -{ - "file_name": "key.rb", - "file_path": "app/models/key.rb", - "size": 1476, - "encoding": "base64", - "content": "IyA9PSBTY2hlbWEgSW5mb3...", - "ref": "master", - "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83", - "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50" -} -``` - -Parameters: - -- `file_path` (required) - Full path to new file. Ex. lib/class.rb -- `ref` (required) - The name of branch, tag or commit - -## Create new file in repository - -``` -POST /projects/:id/repository/files -``` - -Example response: - -```json -{ - "file_name": "app/project.rb", - "branch_name": "master" -} -``` - -Parameters: - -- `file_path` (required) - Full path to new file. Ex. lib/class.rb -- `branch_name` (required) - The name of branch -- `encoding` (optional) - 'text' or 'base64'. Text is default. -- `content` (required) - File content -- `commit_message` (required) - Commit message - -## Update existing file in repository - -``` -PUT /projects/:id/repository/files -``` - -Example response: - -```json -{ - "file_name": "app/project.rb", - "branch_name": "master" -} -``` - -Parameters: - -- `file_path` (required) - Full path to file. Ex. lib/class.rb -- `branch_name` (required) - The name of branch -- `encoding` (optional) - 'text' or 'base64'. Text is default. -- `content` (required) - New file content -- `commit_message` (required) - Commit message - -If the commit fails for any reason we return a 400 error with a non-specific -error message. Possible causes for a failed commit include: -- the `file_path` contained `/../` (attempted directory traversal); -- the new file contents were identical to the current file contents, i.e. the - user tried to make an empty commit; -- the branch was updated by a Git push while the file edit was in progress. - -Currently gitlab-shell has a boolean return code, preventing GitLab from specifying the error. - -## Delete existing file in repository - -``` -DELETE /projects/:id/repository/files -``` - -Example response: - -```json -{ - "file_name": "app/project.rb", - "branch_name": "master" -} -``` - -Parameters: - -- `file_path` (required) - Full path to file. Ex. lib/class.rb -- `branch_name` (required) - The name of branch -- `commit_message` (required) - Commit message diff --git a/doc/api/services.md b/doc/api/services.md deleted file mode 100644 index cbf767d1b251a773520f158229bdb1e21e0c7e22..0000000000000000000000000000000000000000 --- a/doc/api/services.md +++ /dev/null @@ -1,46 +0,0 @@ -# Services - -## GitLab CI - -### Edit GitLab CI service - -Set GitLab CI service for a project. - -``` -PUT /projects/:id/services/gitlab-ci -``` - -Parameters: - -- `token` (required) - CI project token -- `project_url` (required) - CI project URL - -### Delete GitLab CI service - -Delete GitLab CI service settings for a project. - -``` -DELETE /projects/:id/services/gitlab-ci -``` - -## HipChat - -### Edit HipChat service - -Set HipChat service for project. - -``` -PUT /projects/:id/services/hipchat -``` -Parameters: - -- `token` (required) - HipChat token -- `room` (required) - HipChat room name - -### Delete HipChat service - -Delete HipChat service for a project. - -``` -DELETE /projects/:id/services/hipchat -``` diff --git a/doc/api/session.md b/doc/api/session.md deleted file mode 100644 index 47c1c8a7a49d30980b774438b07e23ab013573b3..0000000000000000000000000000000000000000 --- a/doc/api/session.md +++ /dev/null @@ -1,39 +0,0 @@ -# Session - -Login to get private token - -``` -POST /session -``` - -Parameters: - -- `login` (required) - The login of user -- `email` (required if login missing) - The email of user -- `password` (required) - Valid password - -**You can login with both GitLab and LDAP credentials now** - - -```json -{ - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "private_token": "dd34asd13as", - "blocked": false, - "created_at": "2012-05-23T08:00:58Z", - "bio": null, - "skype": "", - "linkedin": "", - "twitter": "", - "website_url": "", - "dark_scheme": false, - "theme_id": 1, - "is_admin": false, - "can_create_group": true, - "can_create_team": true, - "can_create_project": true -} -``` diff --git a/doc/api/system_hooks.md b/doc/api/system_hooks.md deleted file mode 100644 index f9637d8a6c4c18bd8906897dd237bc3cf82b6289..0000000000000000000000000000000000000000 --- a/doc/api/system_hooks.md +++ /dev/null @@ -1,70 +0,0 @@ -# System hooks - -All methods require admin authorization. - -The URL endpoint of the system hooks can be configured in [the admin area under hooks](/admin/hooks). - -## List system hooks - -Get list of system hooks - -``` -GET /hooks -``` - -Parameters: - -- **none** - -```json -[ - { - "id": 3, - "url": "http://example.com/hook", - "created_at": "2013-10-02T10:15:31Z" - } -] -``` - -## Add new system hook hook - -``` -POST /hooks -``` - -Parameters: - -- `url` (required) - The hook URL - -## Test system hook - -``` -GET /hooks/:id -``` - -Parameters: - -- `id` (required) - The ID of hook - -```json -{ - "event_name": "project_create", - "name": "Ruby", - "path": "ruby", - "project_id": 1, - "owner_name": "Someone", - "owner_email": "example@gitlabhq.com" -} -``` - -## Delete system hook - -Deletes a system hook. This is an idempotent API function and returns `200 OK` even if the hook is not available. If the hook is deleted it is also returned as JSON. - -``` -DELETE /hooks/:id -``` - -Parameters: - -- `id` (required) - The ID of hook diff --git a/doc/api/users.md b/doc/api/users.md deleted file mode 100644 index a8b7685b503c463e9e573a25c3cb90fb801b87b3..0000000000000000000000000000000000000000 --- a/doc/api/users.md +++ /dev/null @@ -1,394 +0,0 @@ -# Users - -## List users - -Get a list of users. - -This function takes pagination parameters `page` and `per_page` to restrict the list of users. - -### For normal users - -``` -GET /users -``` - -```json -[ - { - "id": 1, - "username": "john_smith", - "name": "John Smith", - "state": "active", - "avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg", - }, - { - "id": 2, - "username": "jack_smith", - "name": "Jack Smith", - "state": "blocked", - "avatar_url": "http://gravatar.com/../e32131cd8.jpeg", - } -] -``` - -### For admins - -``` -GET /users -``` - -```json -[ - { - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "state": "active", - "created_at": "2012-05-23T08:00:58Z", - "bio": null, - "skype": "", - "linkedin": "", - "twitter": "", - "website_url": "", - "extern_uid": "john.smith", - "provider": "provider_name", - "theme_id": 1, - "color_scheme_id": 2, - "is_admin": false, - "avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg", - "can_create_group": true - }, - { - "id": 2, - "username": "jack_smith", - "email": "jack@example.com", - "name": "Jack Smith", - "state": "blocked", - "created_at": "2012-05-23T08:01:01Z", - "bio": null, - "skype": "", - "linkedin": "", - "twitter": "", - "website_url": "", - "extern_uid": "jack.smith", - "provider": "provider_name", - "theme_id": 1, - "color_scheme_id": 3, - "is_admin": false, - "avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg", - "can_create_group": true, - "can_create_project": true, - "projects_limit": 100 - } -] -``` - -You can search for users by email or username with: `/users?search=John` - -Also see `def search query` in `app/models/user.rb`. - -## Single user - -Get a single user. - -### For user - -``` -GET /users/:id -``` - -Parameters: - -- `id` (required) - The ID of a user - -```json -{ - "id": 1, - "username": "john_smith", - "name": "John Smith", - "state": "active", - "avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg", -} -``` - -### For admin - -``` -GET /users/:id -``` - -Parameters: - -- `id` (required) - The ID of a user - -```json -{ - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "state": "active", - "created_at": "2012-05-23T08:00:58Z", - "bio": null, - "skype": "", - "linkedin": "", - "twitter": "", - "website_url": "", - "extern_uid": "john.smith", - "provider": "provider_name", - "theme_id": 1, - "color_scheme_id": 2, - "is_admin": false, - "can_create_group": true, - "can_create_project": true, - "projects_limit": 100 -} -``` - -## User creation - -Creates a new user. Note only administrators can create new users. - -``` -POST /users -``` - -Parameters: - -- `email` (required) - Email -- `password` (required) - Password -- `username` (required) - Username -- `name` (required) - Name -- `skype` (optional) - Skype ID -- `linkedin` (optional) - LinkedIn -- `twitter` (optional) - Twitter account -- `website_url` (optional) - Website URL -- `projects_limit` (optional) - Number of projects user can create -- `extern_uid` (optional) - External UID -- `provider` (optional) - External provider name -- `bio` (optional) - User's biography -- `admin` (optional) - User is admin - true or false (default) -- `can_create_group` (optional) - User can create groups - true or false -- `confirm` (optional) - Require confirmation - true (default) or false - -## User modification - -Modifies an existing user. Only administrators can change attributes of a user. - -``` -PUT /users/:id -``` - -Parameters: - -- `email` - Email -- `username` - Username -- `name` - Name -- `password` - Password -- `skype` - Skype ID -- `linkedin` - LinkedIn -- `twitter` - Twitter account -- `website_url` - Website URL -- `projects_limit` - Limit projects each user can create -- `extern_uid` - External UID -- `provider` - External provider name -- `bio` - User's biography -- `admin` (optional) - User is admin - true or false (default) -- `can_create_group` (optional) - User can create groups - true or false - -Note, at the moment this method does only return a 404 error, -even in cases where a 409 (Conflict) would be more appropriate, -e.g. when renaming the email address to some existing one. - -## User deletion - -Deletes a user. Available only for administrators. -This is an idempotent function, calling this function for a non-existent user id -still returns a status code `200 OK`. -The JSON response differs if the user was actually deleted or not. -In the former the user is returned and in the latter not. - -``` -DELETE /users/:id -``` - -Parameters: - -- `id` (required) - The ID of the user - -## Current user - -Gets currently authenticated user. - -``` -GET /user -``` - -```json -{ - "id": 1, - "username": "john_smith", - "email": "john@example.com", - "name": "John Smith", - "private_token": "dd34asd13as", - "state": "active", - "created_at": "2012-05-23T08:00:58Z", - "bio": null, - "skype": "", - "linkedin": "", - "twitter": "", - "website_url": "", - "theme_id": 1, - "color_scheme_id": 2, - "is_admin": false, - "can_create_group": true, - "can_create_project": true, - "projects_limit": 100 -} -``` - -## List SSH keys - -Get a list of currently authenticated user's SSH keys. - -``` -GET /user/keys -``` - -```json -[ - { - "id": 1, - "title": "Public key", - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", - "created_at": "2014-08-01T14:47:39.080Z" - }, - { - "id": 3, - "title": "Another Public key", - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", - "created_at": "2014-08-01T14:47:39.080Z" - } -] -``` - -Parameters: - -- **none** - -## List SSH keys for user - -Get a list of a specified user's SSH keys. Available only for admin - -``` -GET /users/:uid/keys -``` - -Parameters: - -- `uid` (required) - id of specified user - -## Single SSH key - -Get a single key. - -``` -GET /user/keys/:id -``` - -Parameters: - -- `id` (required) - The ID of an SSH key - -```json -{ - "id": 1, - "title": "Public key", - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=", - "created_at": "2014-08-01T14:47:39.080Z" -} -``` - -## Add SSH key - -Creates a new key owned by the currently authenticated user. - -``` -POST /user/keys -``` - -Parameters: - -- `title` (required) - new SSH Key's title -- `key` (required) - new SSH key - -```json -{ - "created_at": "2015-01-21T17:44:33.512Z", - "key": "ssh-dss AAAAB3NzaC1kc3MAAACBAMLrhYgI3atfrSD6KDas1b/3n6R/HP+bLaHHX6oh+L1vg31mdUqK0Ac/NjZoQunavoyzqdPYhFz9zzOezCrZKjuJDS3NRK9rspvjgM0xYR4d47oNZbdZbwkI4cTv/gcMlquRy0OvpfIvJtjtaJWMwTLtM5VhRusRuUlpH99UUVeXAAAAFQCVyX+92hBEjInEKL0v13c/egDCTQAAAIEAvFdWGq0ccOPbw4f/F8LpZqvWDydAcpXHV3thwb7WkFfppvm4SZte0zds1FJ+Hr8Xzzc5zMHe6J4Nlay/rP4ewmIW7iFKNBEYb/yWa+ceLrs+TfR672TaAgO6o7iSRofEq5YLdwgrwkMmIawa21FrZ2D9SPao/IwvENzk/xcHu7YAAACAQFXQH6HQnxOrw4dqf0NqeKy1tfIPxYYUZhPJfo9O0AmBW2S36pD2l14kS89fvz6Y1g8gN/FwFnRncMzlLY/hX70FSc/3hKBSbH6C6j8hwlgFKfizav21eS358JJz93leOakJZnGb8XlWvz1UJbwCsnR2VEY8Dz90uIk1l/UqHkA= loic@call", - "title": "ABC", - "id": 4 -} -``` - -Will return created key with status `201 Created` on success. If an -error occurs a `400 Bad Request` is returned with a message explaining the error: - -```json -{ - "message": { - "fingerprint": [ - "has already been taken" - ], - "key": [ - "has already been taken" - ] - } -} -``` - -## Add SSH key for user - -Create new key owned by specified user. Available only for admin - -``` -POST /users/:id/keys -``` - -Parameters: - -- `id` (required) - id of specified user -- `title` (required) - new SSH Key's title -- `key` (required) - new SSH key - -Will return created key with status `201 Created` on success, or `404 Not found` on fail. - -## Delete SSH key for current user - -Deletes key owned by currently authenticated user. -This is an idempotent function and calling it on a key that is already deleted -or not available results in `200 OK`. - -``` -DELETE /user/keys/:id -``` - -Parameters: - -- `id` (required) - SSH key ID - -## Delete SSH key for given user - -Deletes key owned by a specified user. Available only for admin. - -``` -DELETE /users/:uid/keys/:id -``` - -Parameters: - -- `uid` (required) - id of specified user -- `id` (required) - SSH key ID - -Will return `200 OK` on success, or `404 Not found` if either user or key cannot be found. diff --git a/doc/customization/issue_closing.md b/doc/customization/issue_closing.md deleted file mode 100644 index aa65a082a530b1c97011320871a913c0177f18ab..0000000000000000000000000000000000000000 --- a/doc/customization/issue_closing.md +++ /dev/null @@ -1,36 +0,0 @@ -# Issue closing pattern - -If a commit message matches the regular expression below, all issues referenced from -the matched text will be closed. This happens when the commit is pushed or merged -into the default branch of a project. - -When not specified, the default issue_closing_pattern as shown below will be used: - -```bash -((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+) -``` - -For example: - -``` -git commit -m "Awesome commit message (Fix #20, Fixes #21 and Closes #22). This commit is also related to #17 and fixes #18, #19 and #23." -``` - -will close `#20`, `#21`, `#22`, `#18`, `#19` and `#23`, but `#17` won't be closed -as it does not match the pattern. It also works with multiline commit messages. - -Tip: you can test this closing pattern at [http://rubular.com][1]. Use this site -to test your own patterns. - -## Change the pattern - -For Omnibus installs you can change the default pattern in `/etc/gitlab/gitlab.rb`: - -``` -issue_closing_pattern: '((?:[Cc]los(?:e[sd]|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' -``` - -For manual installs you can customize the pattern in [gitlab.yml][0]. - -[0]: https://gitlab.com/gitlab-org/gitlab-ce/blob/40c3675372320febf5264061c9bcd63db2dfd13c/config/gitlab.yml.example#L65 -[1]: http://rubular.com/r/Xmbexed1OJ diff --git a/doc/customization/libravatar.md b/doc/customization/libravatar.md deleted file mode 100644 index ee57fdc65906a7e46ef68a54d3f7924d99768d9d..0000000000000000000000000000000000000000 --- a/doc/customization/libravatar.md +++ /dev/null @@ -1,69 +0,0 @@ -# Use Libravatar service with GitLab - -GitLab by default supports [Gravatar](gravatar.com) avatar service. -Libravatar is a service which delivers your avatar (profile picture) to other websites and their API is -[heavily based on gravatar](http://wiki.libravatar.org/api/). - -This means that it is not complicated to switch to Libravatar avatar service or even self hosted Libravatar server. - -# Configuration - -In [gitlab.yml gravatar section](https://gitlab.com/gitlab-org/gitlab-ce/blob/672bd3902d86b78d730cea809fce312ec49d39d7/config/gitlab.yml.example#L122) set -the configuration options as follows: - -## For HTTP - -```yml - gravatar: - enabled: true - # gravatar URLs: possible placeholders: %{hash} %{size} %{email} - plain_url: "http://cdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" -``` - -## For HTTPS - -```yml - gravatar: - enabled: true - # gravatar URLs: possible placeholders: %{hash} %{size} %{email} - ssl_url: "https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" -``` - -## Self-hosted - -If you are [running your own libravatar service](http://wiki.libravatar.org/running_your_own/) the URL will be different in the configuration -but the important part is to provide the same placeholders so GitLab can parse the URL correctly. - -For example, you host a service on `http://libravatar.example.com` the `plain_url` you need to supply in `gitlab.yml` is - -`http://libravatar.example.com/avatar/%{hash}?s=%{size}&d=identicon` - - -## Omnibus-gitlab example - -In `/etc/gitlab/gitlab.rb`: - -#### For http - -```ruby -gitlab_rails['gravatar_enabled'] = true -gitlab_rails['gravatar_plain_url'] = "http://cdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" -``` - -#### For https - -```ruby -gitlab_rails['gravatar_enabled'] = true -gitlab_rails['gravatar_ssl_url'] = "https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon" -``` - - -Run `sudo gitlab-ctl reconfigure` for changes to take effect. - - -## Default URL for missing images - -[Libravatar supports different sets](http://wiki.libravatar.org/api/) of `missing images` for emails not found on the Libravatar service. - -In order to use a different set other than `identicon`, replace `&d=identicon` portion of the URL with another supported set. -For example, you can use `retro` set in which case the URL would look like: `plain_url: "http://cdn.libravatar.org/avatar/%{hash}?s=%{size}&d=retro"` diff --git a/doc/customization/welcome_message.md b/doc/customization/welcome_message.md deleted file mode 100644 index 6c141d1fb7a1ef39481e11943d6ae98f979aa983..0000000000000000000000000000000000000000 --- a/doc/customization/welcome_message.md +++ /dev/null @@ -1,38 +0,0 @@ -# Customize the complete sign-in page (GitLab Enterprise Edition only) - -Please see [Branded login page](http://doc.gitlab.com/ee/customization/branded_login_page.html) - -# Add a welcome message to the sign-in page (GitLab Community Edition) - -It is possible to add a markdown-formatted welcome message to your GitLab -sign-in page. Users of GitLab Enterprise Edition should use the [branded login -page feature](/ee/customization/branded_login_page.html) instead. - -## Omnibus-gitlab example - -In `/etc/gitlab/gitlab.rb`: - -```ruby -gitlab_rails['extra_sign_in_text'] = <<'EOS' -# ACME GitLab -Welcome to the [ACME](http://www.example.com) GitLab server! -EOS -``` - -Run `sudo gitlab-ctl reconfigure` for changes to take effect. - -## Installation from source - -In `/home/git/gitlab/config/gitlab.yml`: - -```yaml -# snip -production: - # snip - extra: - sign_in_text: | - # ACME GitLab - Welcome to the [ACME](http://www.example.com) GitLab server! -``` - -Run `sudo service gitlab reload` for the change to take effect. diff --git a/doc/development/README.md b/doc/development/README.md deleted file mode 100644 index d5d264be19d784aa4cc60dfe4d339fcd6a13f65f..0000000000000000000000000000000000000000 --- a/doc/development/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Development - -- [Architecture](architecture.md) of GitLab -- [Shell commands](shell_commands.md) in the GitLab codebase -- [Rake tasks](rake_tasks.md) for development -- [CI setup](ci_setup.md) for testing GitLab -- [Sidekiq debugging](sidekiq_debugging.md) -- [UI guide](ui_guide.md) for building GitLab with existing css styles and elements diff --git a/doc/development/architecture.md b/doc/development/architecture.md deleted file mode 100644 index 541af487bb1fc71f34367ce0258408d77f790b62..0000000000000000000000000000000000000000 --- a/doc/development/architecture.md +++ /dev/null @@ -1,188 +0,0 @@ -# GitLab Architecture Overview - -## Software delivery - -There are two editions of GitLab: [Enterprise Edition](https://about.gitlab.com/gitlab-ee/) (EE) and [Community Edition](https://about.gitlab.com/gitlab-ce/) (CE). GitLab CE is delivered via git from the [gitlabhq repository](https://gitlab.com/gitlab-org/gitlab-ce/tree/master). New versions of GitLab are released in stable branches and the master branch is for bleeding edge development. - -EE releases are available not long after CE releases. To obtain the GitLab EE there is a [repository at gitlab.com](https://gitlab.com/subscribers/gitlab-ee). For more information about the release process see the section 'New versions and upgrading' in the readme. - -Both EE and CE require an add-on component called gitlab-shell. It is obtained from the [gitlab-shell repository](https://gitlab.com/gitlab-org/gitlab-shell/tree/master). New versions are usually tags but staying on the master branch will give you the latest stable version. New releases are generally around the same time as GitLab CE releases with exception for informal security updates deemed critical. - -## Physical office analogy - -You can imagine GitLab as a physical office. - -**The repositories** are the goods GitLab handling. -They can be stored in a warehouse. -This can be either a hard disk, or something more complex, such as a NFS filesystem; - -**Nginx** acts like the front-desk. -Users come to Nginx and request actions to be done by workers in the office; - -**The database** is a series of metal file cabinets with information on: - - The goods in the warehouse (metadata, issues, merge requests etc); - - The users coming to the front desk (permissions) - -**Redis** is a communication board with “cubby holes” that can contain tasks for office workers; - -**Sidekiq** is a worker that primarily handles sending out emails. -It takes tasks from the Redis communication board; - -**A Unicorn worker** is a worker that handles quick/mundane tasks. -They work with the communication board (Redis). -Their job description: - - check permissions by checking the user session stored in a Redis “cubby hole”; - - make tasks for Sidekiq; - - fetch stuff from the warehouse or move things around in there; - -**Gitlab-shell** is a third kind of worker that takes orders from a fax machine (SSH) instead of the front desk (HTTP). -Gitlab-shell communicates with Sidekiq via the “communication board” (Redis), and asks quick questions of the Unicorn workers either directly or via the front desk. - -**GitLab Enterprise Edition (the application)** is the collection of processes and business practices that the office is run by. - -## System Layout - -When referring to ~git in the pictures it means the home directory of the git user which is typically /home/git. - -GitLab is primarily installed within the `/home/git` user home directory as `git` user. Within the home directory is where the gitlabhq server software resides as well as the repositories (though the repository location is configurable). - -The bare repositories are located in `/home/git/repositories`. GitLab is a ruby on rails application so the particulars of the inner workings can be learned by studying how a ruby on rails application works. - -To serve repositories over SSH there's an add-on application called gitlab-shell which is installed in `/home/git/gitlab-shell`. - -### Components - -![GitLab Diagram Overview](gitlab_diagram_overview.png) - -A typical install of GitLab will be on GNU/Linux. It uses Nginx or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses `/home/git/gitlab/public` bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and precompiled assets. GitLab serves web pages and a [GitLab API](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/api) using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses redis as a non-persistent database backend for job information, meta data, and incoming jobs. - -The GitLab web app uses MySQL or PostgreSQL for persistent database information (e.g. users, permissions, issues, other meta data). GitLab stores the bare git repositories it serves in `/home/git/repositories` by default. It also keeps default branch and hook information with the bare repository. `/home/git/gitlab-satellites` keeps checked out repositories when performing actions such as a merge request, editing files in the web interface, etc. - -The satellite repository is used by the web interface for editing repositories and the wiki which is also a git repository. When serving repositories over HTTP/HTTPS GitLab utilizes the GitLab API to resolve authorization and access as well as serving git objects. - -The add-on component gitlab-shell serves repositories over SSH. It manages the SSH keys within `/home/git/.ssh/authorized_keys` which should not be manually edited. gitlab-shell accesses the bare repositories directly to serve git objects and communicates with redis to submit jobs to Sidekiq for GitLab to process. gitlab-shell queries the GitLab API to determine authorization and access. - -### Installation Folder Summary - -To summarize here's the [directory structure of the `git` user home directory](../install/structure.md). - -### Processes - - ps aux | grep '^git' - -GitLab has several components to operate. As a system user (i.e. any user that is not the `git` user) it requires a persistent database (MySQL/PostreSQL) and redis database. It also uses Apache httpd or Nginx to proxypass Unicorn. As the `git` user it starts Sidekiq and Unicorn (a simple ruby HTTP server running on port `8080` by default). Under the GitLab user there are normally 4 processes: `unicorn_rails master` (1 process), `unicorn_rails worker` (2 processes), `sidekiq` (1 process). - -### Repository access - -Repositories get accessed via HTTP or SSH. HTTP cloning/push/pull utilizes the GitLab API and SSH cloning is handled by gitlab-shell (previously explained). - -## Troubleshooting - -See the README for more information. - -### Init scripts of the services - -The GitLab init script starts and stops Unicorn and Sidekiq. - -``` -/etc/init.d/gitlab -Usage: service gitlab {start|stop|restart|reload|status} -``` - -Redis (key-value store/non-persistent database) - -``` -/etc/init.d/redis -Usage: /etc/init.d/redis {start|stop|status|restart|condrestart|try-restart} -``` - -SSH daemon - -``` -/etc/init.d/sshd -Usage: /etc/init.d/sshd {start|stop|restart|reload|force-reload|condrestart|try-restart|status} -``` - -Web server (one of the following) - -``` -/etc/init.d/httpd -Usage: httpd {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest} - -$ /etc/init.d/nginx -Usage: nginx {start|stop|restart|reload|force-reload|status|configtest} -``` - -Persistent database (one of the following) - -``` -/etc/init.d/mysqld -Usage: /etc/init.d/mysqld {start|stop|status|restart|condrestart|try-restart|reload|force-reload} - -$ /etc/init.d/postgresql -Usage: /etc/init.d/postgresql {start|stop|restart|reload|force-reload|status} [version ..] -``` - -### Log locations of the services - -Note: `/home/git/` is shorthand for `/home/git`. - -gitlabhq (includes Unicorn and Sidekiq logs) - -- `/home/git/gitlab/log/` contains `application.log`, `production.log`, `sidekiq.log`, `unicorn.stdout.log`, `githost.log`, `satellites.log`, and `unicorn.stderr.log` normally. - -gitlab-shell - -- `/home/git/gitlab-shell/gitlab-shell.log` - -ssh - -- `/var/log/auth.log` auth log (on Ubuntu). -- `/var/log/secure` auth log (on RHEL). - -nginx - -- `/var/log/nginx/` contains error and access logs. - -Apache httpd - -- [Explanation of Apache logs](http://httpd.apache.org/docs/2.2/logs.html). -- `/var/log/apache2/` contains error and output logs (on Ubuntu). -- `/var/log/httpd/` contains error and output logs (on RHEL). - -redis - -- `/var/log/redis/redis.log` there are also log-rotated logs there. - -PostgreSQL - -- `/var/log/postgresql/*` - -MySQL - -- `/var/log/mysql/*` -- `/var/log/mysql.*` - -### GitLab specific config files - -GitLab has configuration files located in `/home/git/gitlab/config/*`. Commonly referenced config files include: - -- `gitlab.yml` - GitLab configuration. -- `unicorn.rb` - Unicorn web server settings. -- `database.yml` - Database connection settings. - -gitlab-shell has a configuration file at `/home/git/gitlab-shell/config.yml`. - -### Maintenance Tasks - -[GitLab](https://gitlab.com/gitlab-org/gitlab-ce/tree/master) provides rake tasks with which you see version information and run a quick check on your configuration to ensure it is configured properly within the application. See [maintenance rake tasks](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/raketasks/maintenance.md). -In a nutshell, do the following: - -``` -sudo -i -u git -cd gitlab -bundle exec rake gitlab:env:info RAILS_ENV=production -bundle exec rake gitlab:check RAILS_ENV=production -``` - -Note: It is recommended to log into the `git` user using `sudo -i -u git` or `sudo su - git`. While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL. diff --git a/doc/development/ci_setup.md b/doc/development/ci_setup.md deleted file mode 100644 index f9b488681820db5041dc5bd1678697eaf0ac981d..0000000000000000000000000000000000000000 --- a/doc/development/ci_setup.md +++ /dev/null @@ -1,46 +0,0 @@ -# CI setup - -This document describes what services we use for testing GitLab and GitLab CI. - -We currently use three CI services to test GitLab: - -1. GitLab CI on [GitHost.io](https://gitlab-ce.githost.io/projects/4/) for the [GitLab.com repo](https://gitlab.com/gitlab-org/gitlab-ce) -2. GitLab CI at ci.gitlab.org to test the private GitLab B.V. repo at dev.gitlab.org -3. [Semephore](https://semaphoreapp.com/gitlabhq/gitlabhq/) for [GitHub.com repo](https://github.com/gitlabhq/gitlabhq) - -| Software @ configuration being tested | GitLab CI (ci.gitlab.org) | GitLab CI (GitHost.io) | Semaphore | -|---------------------------------------|---------------------------|---------------------------------------------------------------------------|-----------| -| GitLab CE @ MySQL | ✓ | ✓ [Core team can trigger builds](https://gitlab-ce.githost.io/projects/4) | | -| GitLab CE @ PostgreSQL | | | ✓ [Core team can trigger builds](https://semaphoreapp.com/gitlabhq/gitlabhq/branches/master) | -| GitLab EE @ MySQL | ✓ | | | -| GitLab CI @ MySQL | ✓ | | | -| GitLab CI @ PostgreSQL | | | ✓ | -| GitLab CI Runner | ✓ | | ✓ | -| GitLab Shell | ✓ | | ✓ | -| GitLab Shell | ✓ | | ✓ | - -Core team has access to trigger builds if needed for GitLab CE. - -We use [these build scripts](https://gitlab.com/gitlab-org/gitlab-ci/blob/master/doc/examples/build_script_gitlab_ce.md) for testing with GitLab CI. - -# Build configuration on [Semaphore](https://semaphoreapp.com/gitlabhq/gitlabhq/) for testing the [GitHub.com repo](https://github.com/gitlabhq/gitlabhq) - -- Language: Ruby -- Ruby version: 2.1.2 -- database.yml: pg - -Build commands - -```bash -sudo apt-get install cmake libicu-dev -y (Setup) -bundle install --deployment --path vendor/bundle (Setup) -cp config/gitlab.yml.example config/gitlab.yml (Setup) -bundle exec rake db:create (Setup) -bundle exec rake spinach (Thread #1) -bundle exec rake spec (thread #2) -bundle exec rake rubocop (thread #3) -bundle exec rake brakeman (thread #4) -bundle exec rake jasmine:ci (thread #5) -``` - -Use rubygems mirror. diff --git a/doc/development/gitlab_diagram_overview.odg b/doc/development/gitlab_diagram_overview.odg deleted file mode 100644 index 9bfc7313ff4cfd7c82fe51aa4b073bef1d413edd..0000000000000000000000000000000000000000 Binary files a/doc/development/gitlab_diagram_overview.odg and /dev/null differ diff --git a/doc/development/gitlab_diagram_overview.png b/doc/development/gitlab_diagram_overview.png deleted file mode 100644 index d9b9eed3d8f6b244dabf5b3074324fcfa774704a..0000000000000000000000000000000000000000 Binary files a/doc/development/gitlab_diagram_overview.png and /dev/null differ diff --git a/doc/development/omnibus.md b/doc/development/omnibus.md deleted file mode 100644 index 0ba354d28a2fcdd60003326bff03ac9910ce6261..0000000000000000000000000000000000000000 --- a/doc/development/omnibus.md +++ /dev/null @@ -1,32 +0,0 @@ -# What you should know about omnibus packages - -Most users install GitLab using our omnibus packages. As a developer it can be -good to know how the omnibus packages differ from what you have on your laptop -when you are coding. - -## Files are owned by root by default - -All the files in the Rails tree (`app/`, `config/` etc.) are owned by 'root' in -omnibus installations. This makes the installation simpler and it provides -extra security. The omnibus reconfigure script contains commands that give -write access to the 'git' user only where needed. - -For example, the 'git' user is allowed to write in the `log/` directory, in -`public/uploads`, and they are allowed to rewrite the `db/schema.rb` file. - -In other cases, the reconfigure script tricks GitLab into not trying to write a -file. For instance, GitLab will generate a `.secret` file if it cannot find one -and write it to the Rails root. In the omnibus packages, reconfigure writes the -`.secret` file first, so that GitLab never tries to write it. - -## Code, data and logs are in separate directories - -The omnibus design separates code (read-only, under `/opt/gitlab`) from data -(read/write, under `/var/opt/gitlab`) and logs (read/write, under -`/var/log/gitlab`). To make this happen the reconfigure script sets custom -paths where it can in GitLab config files, and where there are no path -settings, it uses symlinks. - -For example, `config/gitlab.yml` is treated as data so that file is a symlink. -The same goes for `public/uploads`. The `log/` directory is replaced by omnibus -with a symlink to `/var/log/gitlab/gitlab-rails`. diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md deleted file mode 100644 index 53f8095cb13555b47abf7708bf46e2670c514f25..0000000000000000000000000000000000000000 --- a/doc/development/rake_tasks.md +++ /dev/null @@ -1,29 +0,0 @@ -# Rake tasks for developers - -## Setup db with developer seeds - -Note that if your db user does not have advanced privileges you must create the db manually before running this command. - -``` -bundle exec rake setup -``` - -The `setup` task is a alias for `gitlab:setup`. -This tasks calls `db:setup` to create the database, calls `add_limits_mysql` that adds limits to the database schema in case of a MySQL database and fianlly it calls `db:seed_fu` to seed the database. -Note: `db:setup` calls `db:seed` but this does nothing. - -## Run tests - -This runs all test suites present in GitLab. - -``` -bundle exec rake test -``` - -## Generate searchable docs for source code - -You can find results under the `doc/code` directory. - -``` -bundle exec rake gitlab:generate_docs -``` diff --git a/doc/development/shell_commands.md b/doc/development/shell_commands.md deleted file mode 100644 index 821027f43fa391ab66266d080e8ac96c2eb29006..0000000000000000000000000000000000000000 --- a/doc/development/shell_commands.md +++ /dev/null @@ -1,179 +0,0 @@ -# Guidelines for shell commands in the GitLab codebase - -This document contains guidelines for working with processes and files in the GitLab codebase. -These guidelines are meant to make your code more reliable _and_ secure. - -## References - -- [Google Ruby Security Reviewer's Guide](https://code.google.com/p/ruby-security/wiki/Guide) -- [OWASP Command Injection](https://www.owasp.org/index.php/Command_Injection) -- [Ruby on Rails Security Guide Command Line Injection](http://guides.rubyonrails.org/security.html#command-line-injection) - -## Use File and FileUtils instead of shell commands - -Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it. Use the Ruby API if it exists. - -```ruby -# Wrong -system "mkdir -p tmp/special/directory" -# Better (separate tokens) -system *%W(mkdir -p tmp/special/directory) -# Best (do not use a shell command) -FileUtils.mkdir_p "tmp/special/directory" - -# Wrong -contents = `cat #{filename}` -# Correct -contents = File.read(filename) - -# Sometimes a shell command is just the best solution. The example below has no -# user input, and is hard to implement correctly in Ruby: delete all files and -# directories older than 120 minutes under /some/path, but not /some/path -# itself. -Gitlab::Popen.popen(%W(find /some/path -not -path /some/path -mmin +120 -delete)) -``` - -This coding style could have prevented CVE-2013-4490. - -## Bypass the shell by splitting commands into separate tokens - -When we pass shell commands as a single string to Ruby, Ruby will let `/bin/sh` evaluate the entire string. Essentially, we are asking the shell to evaluate a one-line script. This creates a risk for shell injection attacks. It is better to split the shell command into tokens ourselves. Sometimes we use the scripting capabilities of the shell to change the working directory or set environment variables. All of this can also be achieved securely straight from Ruby - -```ruby -# Wrong -system "cd /home/git/gitlab && bundle exec rake db:#{something} RAILS_ENV=production" -# Correct -system({'RAILS_ENV' => 'production'}, *%W(bundle exec rake db:#{something}), chdir: '/home/git/gitlab') - -# Wrong -system "touch #{myfile}" -# Better -system "touch", myfile -# Best (do not run a shell command at all) -FileUtils.touch myfile -``` - -This coding style could have prevented CVE-2013-4546. - -## Separate options from arguments with -- - -Make the difference between options and arguments clear to the argument parsers of system commands with `--`. This is supported by many but not all Unix commands. - -To understand what `--` does, consider the problem below. - -``` -# Example -$ echo hello > -l -$ cat -l -cat: illegal option -- l -usage: cat [-benstuv] [file ...] -``` - -In the example above, the argument parser of `cat` assumes that `-l` is an option. The solution in the example above is to make it clear to `cat` that `-l` is really an argument, not an option. Many Unix command line tools follow the convention of separating options from arguments with `--`. - -``` -# Example (continued) -$ cat -- -l -hello -``` - -In the GitLab codebase, we avoid the option/argument ambiguity by _always_ using `--`. - -```ruby -# Wrong -system(*%W(git branch -d #{branch_name})) -# Correct -system(*%W(git branch -d -- #{branch_name})) -``` - -This coding style could have prevented CVE-2013-4582. - -## Do not use the backticks - -Capturing the output of shell commands with backticks reads nicely, but you are forced to pass the command as one string to the shell. We explained above that this is unsafe. In the main GitLab codebase, the solution is to use `Gitlab::Popen.popen` instead. - -```ruby -# Wrong -logs = `cd #{repo_dir} && git log` -# Correct -logs, exit_status = Gitlab::Popen.popen(%W(git log), repo_dir) - -# Wrong -user = `whoami` -# Correct -user, exit_status = Gitlab::Popen.popen(%W(whoami)) -``` - -In other repositories, such as gitlab-shell you can also use `IO.popen`. - -```ruby -# Safe IO.popen example -logs = IO.popen(%W(git log), chdir: repo_dir) { |p| p.read } -``` - -Note that unlike `Gitlab::Popen.popen`, `IO.popen` does not capture standard error. - -## Avoid user input at the start of path strings - -Various methods for opening and reading files in Ruby can be used to read the -standard output of a process instead of a file. The following two commands do -roughly the same: - -``` -`touch /tmp/pawned-by-backticks` -File.read('|touch /tmp/pawned-by-file-read') -``` - -The key is to open a 'file' whose name starts with a `|`. -Affected methods include Kernel#open, File::read, File::open, IO::open and IO::read. - -You can protect against this behavior of 'open' and 'read' by ensuring that an -attacker cannot control the start of the filename string you are opening. For -instance, the following is sufficient to protect against accidentally starting -a shell command with `|`: - -``` -# we assume repo_path is not controlled by the attacker (user) -path = File.join(repo_path, user_input) -# path cannot start with '|' now. -File.read(path) -``` - -If you have to use user input a relative path, prefix `./` to the path. - -Prefixing user-supplied paths also offers extra protection against paths -starting with `-` (see the discussion about using `--` above). - -## Guard against path traversal - -Path traversal is a security where the program (GitLab) tries to restrict user -access to a certain directory on disk, but the user manages to open a file -outside that directory by taking advantage of the `../` path notation. - -``` -# Suppose the user gave us a path and they are trying to trick us -user_input = '../other-repo.git/other-file' - -# We look up the repo path somewhere -repo_path = 'repositories/user-repo.git' - -# The intention of the code below is to open a file under repo_path, but -# because the user used '..' she can 'break out' into -# 'repositories/other-repo.git' -full_path = File.join(repo_path, user_input) -File.open(full_path) do # Oops! -``` - -A good way to protect against this is to compare the full path with its -'absolute path' according to Ruby's `File.absolute_path`. - -``` -full_path = File.join(repo_path, user_input) -if full_path != File.absolute_path(full_path) - raise "Invalid path: #{full_path.inspect}" -end - -File.open(full_path) do # Etc. -``` - -A check like this could have avoided CVE-2013-4583. diff --git a/doc/development/sidekiq_debugging.md b/doc/development/sidekiq_debugging.md deleted file mode 100644 index cea11e5f126601e31c1886de25792f2b77461150..0000000000000000000000000000000000000000 --- a/doc/development/sidekiq_debugging.md +++ /dev/null @@ -1,14 +0,0 @@ -# Sidekiq debugging - -## Log arguments to Sidekiq jobs - -If you want to see what arguments are being passed to Sidekiq jobs you can set -the SIDEKIQ_LOG_ARGUMENTS environment variable. - -``` -SIDEKIQ_LOG_ARGUMENTS=1 bundle exec foreman start -``` - -It is not recommend to enable this setting in production because some Sidekiq -jobs (such as sending a password reset email) take secret arguments (for -example the password reset token). diff --git a/doc/development/ui_guide.md b/doc/development/ui_guide.md deleted file mode 100644 index 2f01defc11d8a7b474c02f825314b6c0fc7c9d0a..0000000000000000000000000000000000000000 --- a/doc/development/ui_guide.md +++ /dev/null @@ -1,12 +0,0 @@ -# UI Guide for building GitLab - -## Best practices for creating new pages in GitLab - -TODO: write some best practices when develop GitLab features. - -## GitLab UI development kit - -We created a page inside GitLab where you can check commonly used html and css elements. - -When you run GitLab instance locally - just visit http://localhost:3000/help/ui page to see UI examples -you can use during GitLab development. diff --git a/doc/hooks/custom_hooks.md b/doc/hooks/custom_hooks.md deleted file mode 100644 index f7d4f3de68b3cccf22ddf656cd5d35e2d774894c..0000000000000000000000000000000000000000 --- a/doc/hooks/custom_hooks.md +++ /dev/null @@ -1,41 +0,0 @@ -# Custom Git Hooks - -**Note: Custom git hooks must be configured on the filesystem of the GitLab -server. Only GitLab server administrators will be able to complete these tasks. -Please explore webhooks as an option if you do not have filesystem access.** - -Git natively supports hooks that are executed on different actions. -Examples of server-side git hooks include pre-receive, post-receive, and update. -See -[Git SCM Server-Side Hooks](http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#Server-Side-Hooks) -for more information about each hook type. - -As of gitlab-shell version 2.2.0 (which requires GitLab 7.5+), GitLab -administrators can add custom git hooks to any GitLab project. - -## Setup - -Normally, git hooks are placed in the repository or project's `hooks` directory. -GitLab creates a symlink from each project's `hooks` directory to the -gitlab-shell `hooks` directory for ease of maintenance between gitlab-shell -upgrades. As such, custom hooks are implemented a little differently. Behavior -is exactly the same once the hook is created, though. Follow these steps to -set up a custom hook. - -1. Pick a project that needs a custom git hook. -1. On the GitLab server, navigate to the project's repository directory. -For an installation from source the path is usually -`/home/git/repositories//.git`. For Omnibus installs the path is -usually `/var/opt/gitlab/git-data/repositories//.git`. -1. Create a new directory in this location called `custom_hooks`. -1. Inside the new `custom_hooks` directory, create a file with a name matching -the hook type. For a pre-receive hook the file name should be `pre-receive` with -no extension. -1. Make the hook file executable and make sure it's owned by git. -1. Write the code to make the git hook function as expected. Hooks can be -in any language. Ensure the 'shebang' at the top properly reflects the language -type. For example, if the script is in Ruby the shebang will probably be -`#!/usr/bin/env ruby`. - -That's it! Assuming the hook code is properly implemented the hook will fire -as appropriate. diff --git a/doc/install/README.md b/doc/install/README.md deleted file mode 100644 index 239f5f301ec209eb76170ca4ffa54b22d3ac1539..0000000000000000000000000000000000000000 --- a/doc/install/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Installation - -- [Installation](installation.md) -- [Requirements](requirements.md) -- [Structure](structure.md) -- [Database MySQL](database_mysql.md) diff --git a/doc/install/database_mysql.md b/doc/install/database_mysql.md deleted file mode 100644 index 362c492d0acb17bd0f0931269db75d125df31c1b..0000000000000000000000000000000000000000 --- a/doc/install/database_mysql.md +++ /dev/null @@ -1,54 +0,0 @@ -# Database MySQL - -## Note - -We do not recommend using MySQL due to various issues. For example, case [(in)sensitivity](https://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html) and [problems](http://bugs.mysql.com/bug.php?id=65830) that [suggested](http://bugs.mysql.com/bug.php?id=50909) [fixes](http://bugs.mysql.com/bug.php?id=65830) [have](http://bugs.mysql.com/bug.php?id=63164). - -## MySQL - - # Install the database packages - sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev - - # Ensure you have MySQL version 5.5.14 or later - mysql --version - - # Pick a MySQL root password (can be anything), type it and press enter - # Retype the MySQL root password and press enter - - # Secure your installation - sudo mysql_secure_installation - - # Login to MySQL - mysql -u root -p - - # Type the MySQL root password - - # Create a user for GitLab - # do not type the 'mysql>', this is part of the prompt - # change $password in the command below to a real password you pick - mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY '$password'; - - # Ensure you can use the InnoDB engine which is necessary to support long indexes - # If this fails, check your MySQL config files (e.g. `/etc/mysql/*.cnf`, `/etc/mysql/conf.d/*`) for the setting "innodb = off" - mysql> SET storage_engine=INNODB; - - # Create the GitLab production database - mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; - - # Grant the GitLab user necessary permissions on the database - mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES ON `gitlabhq_production`.* TO 'git'@'localhost'; - - # Quit the database session - mysql> \q - - # Try connecting to the new database with the new user - sudo -u git -H mysql -u git -p -D gitlabhq_production - - # Type the password you replaced $password with earlier - - # You should now see a 'mysql>' prompt - - # Quit the database session - mysql> \q - - # You are done installing the database and can go back to the rest of the installation. diff --git a/doc/install/installation.md b/doc/install/installation.md deleted file mode 100644 index a61a40ebd160c62c4c689ac9fe341647edd43564..0000000000000000000000000000000000000000 --- a/doc/install/installation.md +++ /dev/null @@ -1,462 +0,0 @@ -# Installation from source - -## Consider the Omnibus package installation - -Since an installation from source is a lot of work and error prone we strongly recommend the fast and reliable [Omnibus package installation](https://about.gitlab.com/downloads/) (deb/rpm). - -## Select Version to Install - -Make sure you view [this installation guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md) from the tag (version) of GitLab you would like to install. -In most cases this should be the highest numbered production tag (without rc in it). -You can select the tag in the version dropdown in the top left corner of GitLab (below the menu bar). - -If the highest number stable branch is unclear please check the [GitLab Blog](https://about.gitlab.com/blog/) for installation guide links by version. - -## Important Notes - -This guide is long because it covers many cases and includes all commands you need, this is [one of the few installation scripts that actually works out of the box](https://twitter.com/robinvdvleuten/status/424163226532986880). - -This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [doc/install/requirements.md](./requirements.md) for hardware and operating system requirements. If you want to install on RHEL/CentOS we recommend using the [Omnibus packages](https://about.gitlab.com/downloads/). - -This is the official installation guide to set up a production server. To set up a **development installation** or for many other installation options please see [the installation section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#installation). - -The following steps have been known to work. Please **use caution when you deviate** from this guide. Make sure you don't violate any assumptions GitLab makes about its environment. For example many people run into permission problems because they changed the location of directories or run services as the wrong user. - -If you find a bug/error in this guide please **submit a merge request** -following the -[contributing guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md). - -## Overview - -The GitLab installation consists of setting up the following components: - -1. Packages / Dependencies -1. Ruby -1. System Users -1. Database -1. Redis -1. GitLab -1. Nginx - -## 1. Packages / Dependencies - -`sudo` is not installed on Debian by default. Make sure your system is -up-to-date and install it. - - # run as root! - apt-get update -y - apt-get upgrade -y - apt-get install sudo -y - -**Note:** During this installation some files will need to be edited manually. If you are familiar with vim set it as default editor with the commands below. If you are not familiar with vim please skip this and keep using the default editor. - - # Install vim and set as default editor - sudo apt-get install -y vim - sudo update-alternatives --set editor /usr/bin/vim.basic - -Install the required packages (needed to compile Ruby and native extensions to Ruby gems): - - sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev curl openssh-server redis-server checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev logrotate python-docutils pkg-config cmake libkrb5-dev nodejs - -Make sure you have the right version of Git installed - - # Install Git - sudo apt-get install -y git-core - - # Make sure Git is version 1.7.10 or higher, for example 1.7.12 or 2.0.0 - git --version - -Is the system packaged Git too old? Remove it and compile from source. - - # Remove packaged Git - sudo apt-get remove git-core - - # Install dependencies - sudo apt-get install -y libcurl4-openssl-dev libexpat1-dev gettext libz-dev libssl-dev build-essential - - # Download and compile from source - cd /tmp - curl -L --progress https://www.kernel.org/pub/software/scm/git/git-2.1.2.tar.gz | tar xz - cd git-2.1.2/ - ./configure - make prefix=/usr/local all - - # Install into /usr/local/bin - sudo make prefix=/usr/local install - - # When editing config/gitlab.yml (Step 5), change the git -> bin_path to /usr/local/bin/git - -**Note:** In order to receive mail notifications, make sure to install a mail server. By default, Debian is shipped with exim4 but this [has problems](https://github.com/gitlabhq/gitlabhq/issues/4866#issuecomment-32726573) while Ubuntu does not ship with one. The recommended mail server is postfix and you can install it with: - - sudo apt-get install -y postfix - -Then select 'Internet Site' and press enter to confirm the hostname. - -## 2. Ruby - -The use of Ruby version managers such as [RVM](http://rvm.io/), [rbenv](https://github.com/sstephenson/rbenv) or [chruby](https://github.com/postmodern/chruby) with GitLab in production frequently leads to hard to diagnose problems. For example, GitLab Shell is called from OpenSSH and having a version manager can prevent pushing and pulling over SSH. Version managers are not supported and we strongly advise everyone to follow the instructions below to use a system Ruby. - -Remove the old Ruby 1.8 if present - - sudo apt-get remove ruby1.8 - -Download Ruby and compile it: - - mkdir /tmp/ruby && cd /tmp/ruby - curl -L --progress http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.6.tar.gz | tar xz - cd ruby-2.1.6 - ./configure --disable-install-rdoc - make - sudo make install - -Install the Bundler Gem: - - sudo gem install bundler --no-ri --no-rdoc - -## 3. System Users - -Create a `git` user for GitLab: - - sudo adduser --disabled-login --gecos 'GitLab' git - -## 4. Database - -We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](database_mysql.md). *Note*: because we need to make use of extensions you need at least pgsql 9.1. - - # Install the database packages - sudo apt-get install -y postgresql postgresql-client libpq-dev - - # Login to PostgreSQL - sudo -u postgres psql -d template1 - - # Create a user for GitLab - # Do not type the 'template1=#', this is part of the prompt - template1=# CREATE USER git CREATEDB; - - # Create the GitLab production database & grant all privileges on database - template1=# CREATE DATABASE gitlabhq_production OWNER git; - - # Quit the database session - template1=# \q - - # Try connecting to the new database with the new user - sudo -u git -H psql -d gitlabhq_production - - # Quit the database session - gitlabhq_production> \q - -## 5. Redis - - sudo apt-get install redis-server - - # Configure redis to use sockets - sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.orig - - # Disable Redis listening on TCP by setting 'port' to 0 - sed 's/^port .*/port 0/' /etc/redis/redis.conf.orig | sudo tee /etc/redis/redis.conf - - # Enable Redis socket for default Debian / Ubuntu path - echo 'unixsocket /var/run/redis/redis.sock' | sudo tee -a /etc/redis/redis.conf - # Grant permission to the socket to all members of the redis group - echo 'unixsocketperm 770' | sudo tee -a /etc/redis/redis.conf - - # Create the directory which contains the socket - mkdir /var/run/redis - chown redis:redis /var/run/redis - chmod 755 /var/run/redis - # Persist the directory which contains the socket, if applicable - if [ -d /etc/tmpfiles.d ]; then - echo 'd /var/run/redis 0755 redis redis 10d -' | sudo tee -a /etc/tmpfiles.d/redis.conf - fi - - # Activate the changes to redis.conf - sudo service redis-server restart - - # Add git to the redis group - sudo usermod -aG redis git - -## 6. GitLab - - # We'll install GitLab into home directory of the user "git" - cd /home/git - -### Clone the Source - - # Clone GitLab repository - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 7-10-stable gitlab - -**Note:** You can change `7-10-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! - -### Configure It - - # Go to GitLab installation folder - cd /home/git/gitlab - - # Copy the example GitLab config - sudo -u git -H cp config/gitlab.yml.example config/gitlab.yml - - # Update GitLab config file, follow the directions at top of file - sudo -u git -H editor config/gitlab.yml - - # Make sure GitLab can write to the log/ and tmp/ directories - sudo chown -R git log/ - sudo chown -R git tmp/ - sudo chmod -R u+rwX,go-w log/ - sudo chmod -R u+rwX tmp/ - - # Create directory for satellites - sudo -u git -H mkdir /home/git/gitlab-satellites - sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites - - # Make sure GitLab can write to the tmp/pids/ and tmp/sockets/ directories - sudo chmod -R u+rwX tmp/pids/ - sudo chmod -R u+rwX tmp/sockets/ - - # Make sure GitLab can write to the public/uploads/ directory - sudo chmod -R u+rwX public/uploads - - # Copy the example Unicorn config - sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb - - # Find number of cores - nproc - - # Enable cluster mode if you expect to have a high load instance - # Ex. change amount of workers to 3 for 2GB RAM server - # Set the number of workers to at least the number of cores - sudo -u git -H editor config/unicorn.rb - - # Copy the example Rack attack config - sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb - - # Configure Git global settings for git user, useful when editing via web - # Edit user.email according to what is set in gitlab.yml - sudo -u git -H git config --global user.name "GitLab" - sudo -u git -H git config --global user.email "example@example.com" - sudo -u git -H git config --global core.autocrlf input - - # Configure Redis connection settings - sudo -u git -H cp config/resque.yml.example config/resque.yml - - # Change the Redis socket path if you are not using the default Debian / Ubuntu configuration - sudo -u git -H editor config/resque.yml - -**Important Note:** Make sure to edit both `gitlab.yml` and `unicorn.rb` to match your setup. - -**Note:** If you want to use HTTPS, see [Using HTTPS](#using-https) for the additional steps. - -### Configure GitLab DB Settings - - # PostgreSQL only: - sudo -u git cp config/database.yml.postgresql config/database.yml - - # MySQL only: - sudo -u git cp config/database.yml.mysql config/database.yml - - # MySQL and remote PostgreSQL only: - # Update username/password in config/database.yml. - # You only need to adapt the production settings (first part). - # If you followed the database guide then please do as follows: - # Change 'secure password' with the value you have given to $password - # You can keep the double quotes around the password - sudo -u git -H editor config/database.yml - - # PostgreSQL and MySQL: - # Make config/database.yml readable to git only - sudo -u git -H chmod o-rwx config/database.yml - -### Install Gems - -**Note:** As of bundler 1.5.2, you can invoke `bundle install -jN` (where `N` the number of your processor cores) and enjoy the parallel gems installation with measurable difference in completion time (~60% faster). Check the number of your cores with `nproc`. For more information check this [post](http://robots.thoughtbot.com/parallel-gem-installing-using-bundler). First make sure you have bundler >= 1.5.2 (run `bundle -v`) as it addresses some [issues](https://devcenter.heroku.com/changelog-items/411) that were [fixed](https://github.com/bundler/bundler/pull/2817) in 1.5.2. - - # For PostgreSQL (note, the option says "without ... mysql") - sudo -u git -H bundle install --deployment --without development test mysql aws - - # Or if you use MySQL (note, the option says "without ... postgres") - sudo -u git -H bundle install --deployment --without development test postgres aws - -### Install GitLab Shell - -GitLab Shell is an SSH access and repository management software developed specially for GitLab. - - # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed): - sudo -u git -H bundle exec rake gitlab:shell:install[v2.6.2] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production - - # By default, the gitlab-shell config is generated from your main GitLab config. - # You can review (and modify) the gitlab-shell config as follows: - sudo -u git -H editor /home/git/gitlab-shell/config.yml - -**Note:** If you want to use HTTPS, see [Using HTTPS](#using-https) for the additional steps. - -### Initialize Database and Activate Advanced Features - - sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production - - # Type 'yes' to create the database tables. - - # When done you see 'Administrator account created:' - -**Note:** You can set the Administrator/root password by supplying it in environmental variable `GITLAB_ROOT_PASSWORD` as seen below. If you don't set the password (and it is set to the default one) please wait with exposing GitLab to the public internet until the installation is done and you've logged into the server the first time. During the first login you'll be forced to change the default password. - - sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production GITLAB_ROOT_PASSWORD=yourpassword - -### Install Init Script - -Download the init script (will be `/etc/init.d/gitlab`): - - sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab - -And if you are installing with a non-default folder or user copy and edit the defaults file: - - sudo cp lib/support/init.d/gitlab.default.example /etc/default/gitlab - -If you installed GitLab in another directory or as a user other than the default you should change these settings in `/etc/default/gitlab`. Do not edit `/etc/init.d/gitlab` as it will be changed on upgrade. - -Make GitLab start on boot: - - sudo update-rc.d gitlab defaults 21 - -### Setup Logrotate - - sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab - -### Check Application Status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -### Compile Assets - - sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production - -### Start Your GitLab Instance - - sudo service gitlab start - # or - sudo /etc/init.d/gitlab restart - -## 7. Nginx - -**Note:** Nginx is the officially supported web server for GitLab. If you cannot or do not want to use Nginx as your web server, have a look at the [GitLab recipes](https://gitlab.com/gitlab-org/gitlab-recipes/). - -### Installation - - sudo apt-get install -y nginx - -### Site Configuration - -Copy the example site config: - - sudo cp lib/support/nginx/gitlab /etc/nginx/sites-available/gitlab - sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab - -Make sure to edit the config file to match your setup: - - # Change YOUR_SERVER_FQDN to the fully-qualified - # domain name of your host serving GitLab. - sudo editor /etc/nginx/sites-available/gitlab - -**Note:** If you want to use HTTPS, replace the `gitlab` Nginx config with `gitlab-ssl`. See [Using HTTPS](#using-https) for HTTPS configuration details. - -### Test Configuration - -Validate your `gitlab` or `gitlab-ssl` Nginx config file with the following command: - - sudo nginx -t - -You should receive `syntax is okay` and `test is successful` messages. If you receive errors check your `gitlab` or `gitlab-ssl` Nginx config file for typos, etc. as indicated in the error message given. - -### Restart - - sudo service nginx restart - -## Done! - -### Double-check Application Status - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations on successfully installing GitLab! - -NOTE: Supply `SANITIZE=true` environment variable to `gitlab:check` to omit project names from the output of the check command. - -### Initial Login - -Visit YOUR_SERVER in your web browser for your first GitLab login. The setup has created a default admin account for you. You can use it to log in: - - root - 5iveL!fe - -**Important Note:** On login you'll be prompted to change the password. - -**Enjoy!** - -You can use `sudo service gitlab start` and `sudo service gitlab stop` to start and stop GitLab. - -## Advanced Setup Tips - -### Using HTTPS - -To use GitLab with HTTPS: - -1. In `gitlab.yml`: - 1. Set the `port` option in section 1 to `443`. - 1. Set the `https` option in section 1 to `true`. -1. In the `config.yml` of gitlab-shell: - 1. Set `gitlab_url` option to the HTTPS endpoint of GitLab (e.g. `https://git.example.com`). - 1. Set the certificates using either the `ca_file` or `ca_path` option. -1. Use the `gitlab-ssl` Nginx example config instead of the `gitlab` config. - 1. Update `YOUR_SERVER_FQDN`. - 1. Update `ssl_certificate` and `ssl_certificate_key`. - 1. Review the configuration file and consider applying other security and performance enhancing features. - -Using a self-signed certificate is discouraged but if you must use it follow the normal directions then: - -1. Generate a self-signed SSL certificate: - - ``` - mkdir -p /etc/nginx/ssl/ - cd /etc/nginx/ssl/ - sudo openssl req -newkey rsa:2048 -x509 -nodes -days 3560 -out gitlab.crt -keyout gitlab.key - sudo chmod o-r gitlab.key - ``` -1. In the `config.yml` of gitlab-shell set `self_signed_cert` to `true`. - -### Additional Markup Styles - -Apart from the always supported markdown style there are other rich text files that GitLab can display. But you might have to install a dependency to do so. Please see the [github-markup gem readme](https://github.com/gitlabhq/markup#markups) for more information. - -### Custom Redis Connection - -If you'd like Resque to connect to a Redis server on a non-standard port or on a different host, you can configure its connection string via the `config/resque.yml` file. - - # example - production: redis://redis.example.tld:6379 - -If you want to connect the Redis server via socket, then use the "unix:" URL scheme and the path to the Redis socket file in the `config/resque.yml` file. - - # example - production: unix:/path/to/redis/socket - -### Custom SSH Connection - -If you are running SSH on a non-standard port, you must change the GitLab user's SSH config. - - # Add to /home/git/.ssh/config - host localhost # Give your setup a name (here: override localhost) - user git # Your remote git user - port 2222 # Your port number - hostname 127.0.0.1; # Your server name or IP - -You also need to change the corresponding options (e.g. `ssh_user`, `ssh_host`, `admin_uri`) in the `config\gitlab.yml` file. - -### LDAP Authentication - -You can configure LDAP authentication in `config/gitlab.yml`. Please restart GitLab after editing this file. - -### Using Custom Omniauth Providers - -See the [omniauth integration document](../integration/omniauth.md) diff --git a/doc/install/requirements.md b/doc/install/requirements.md deleted file mode 100644 index 7a3216dd2d2b517064b27a40d5a127174286c8b0..0000000000000000000000000000000000000000 --- a/doc/install/requirements.md +++ /dev/null @@ -1,109 +0,0 @@ -# Requirements - -## Operating Systems - -### Supported Unix distributions - -- Ubuntu -- Debian -- CentOS -- Red Hat Enterprise Linux (please use the CentOS packages and instructions) -- Scientific Linux (please use the CentOS packages and instructions) -- Oracle Linux (please use the CentOS packages and instructions) - -For the installations options please see [the installation page on the GitLab website](https://about.gitlab.com/installation/). - -### Unsupported Unix distributions - -- OS X -- Arch Linux -- Fedora -- Gentoo -- FreeBSD - -On the above unsupported distributions is still possible to install GitLab yourself. -Please see the [installation from source guide](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md) and the [unofficial installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) on the public wiki for more information. - -### Non-Unix operating systems such as Windows - -GitLab is developed for Unix operating systems. -GitLab does **not** run on Windows and we have no plans of supporting it in the near future. -Please consider using a virtual machine to run GitLab. - -## Ruby versions - -GitLab requires Ruby (MRI) 2.0 or 2.1 -You will have to use the standard MRI implementation of Ruby. -We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/) but GitLab needs several Gems that have native extensions. - -## Hardware requirements - -### Storage - -The necessary hard drive space largely depends on the size of the repos you want to store in GitLab but as a *rule of thumb* you should have at least twice as much free space as all your repos combined take up. You need twice the storage because [GitLab satellites](structure.md) contain an extra copy of each repo. - -If you want to be flexible about growing your hard drive space in the future consider mounting it using LVM so you can add more hard drives when you need them. - -Apart from a local hard drive you can also mount a volume that supports the network file system (NFS) protocol. This volume might be located on a file server, a network attached storage (NAS) device, a storage area network (SAN) or on an Amazon Web Services (AWS) Elastic Block Store (EBS) volume. - -If you have enough RAM memory and a recent CPU the speed of GitLab is mainly limited by hard drive seek times. Having a fast drive (7200 RPM and up) or a solid state drive (SSD) will improve the responsiveness of GitLab. - -### CPU - -- 1 core works supports up to 100 users but the application can be a bit slower due to having all workers and background jobs running on the same core -- **2 cores** is the **recommended** number of cores and supports up to 500 users -- 4 cores supports up to 2,000 users -- 8 cores supports up to 5,000 users -- 16 cores supports up to 10,000 users -- 32 cores supports up to 20,000 users -- 64 cores supports up to 40,000 users - -### Memory - -You need at least 2GB of addressable memory (RAM + swap) to install and use GitLab! -With less memory GitLab will give strange errors during the reconfigure run and 500 errors during usage. - -- 512MB RAM + 1.5GB of swap is the absolute minimum but we strongly **advise against** this amount of memory. See the unicorn worker section below for more advise. -- 1GB RAM + 1GB swap supports up to 100 users -- **2GB RAM** is the **recommended** memory size and supports up to 500 users -- 4GB RAM supports up to 2,000 users -- 8GB RAM supports up to 5,000 users -- 16GB RAM supports up to 10,000 users -- 32GB RAM supports up to 20,000 users -- 64GB RAM supports up to 40,000 users - -Notice: The 25 workers of Sidekiq will show up as separate processes in your process overview (such as top or htop) but they share the same RAM allocation since Sidekiq is a multithreaded application. - -## Unicorn Workers - -It's possible to increase the amount of unicorn workers and this will usually help for to reduce the response time of the applications and increase the ability to handle parallel requests. - -For most instances we recommend using: CPU cores + 1 = unicorn workers. -So for a machine with 2 cores, 3 unicorn workers is ideal. - -For all machines that have 1GB and up we recommend a minimum of three unicorn workers. -If you have a 512MB machine with a magnetic (non-SSD) swap drive we recommend to configure only one Unicorn worker to prevent excessive swapping. -With one Unicorn worker only git over ssh access will work because the git over HTTP access requires two running workers (one worker to receive the user request and one worker for the authorization check). -If you have a 512MB machine with a SSD drive you can use two Unicorn workers, this will allow HTTP access although it will be slow due to swapping. - -To change the Unicorn workers when you have the Omnibus package please see [the Unicorn settings in the Omnibus GitLab documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/unicorn.md#unicorn-settings). - -## Database - -If you want to run the database separately, the **recommended** database size is **1 MB per user**. - -## Redis and Sidekiq - -Redis stores all user sessions and the background task queue. -The storage requirements for Redis are minimal, about 25kB per user. -Sidekiq processes the background jobs with a multithreaded process. -This process starts with the entire Rails stack (200MB+) but it can grow over time due to memory leaks. -On a very active server (10,000 active users) the Sidekiq process can use 1GB+ of memory. - -## Supported web browsers - -- Chrome (Latest stable version) -- Firefox (Latest released version and [latest ESR version](https://www.mozilla.org/en-US/firefox/organizations/)) -- Safari 7+ (known problem: required fields in html5 do not work) -- Opera (Latest released version) -- IE 10+ \ No newline at end of file diff --git a/doc/install/structure.md b/doc/install/structure.md deleted file mode 100644 index 5c03f073c18c57094dc1d35d82f06eb318e4ebf1..0000000000000000000000000000000000000000 --- a/doc/install/structure.md +++ /dev/null @@ -1,21 +0,0 @@ -# GitLab directory structure - -This is the directory structure you will end up with following the instructions in the Installation Guide. - - |-- home - | |-- git - | |-- .ssh - | |-- gitlab - | |-- gitlab-satellites - | |-- gitlab-shell - | |-- repositories - -* `/home/git/.ssh` - contains openssh settings. Specifically the `authorized_keys` file managed by gitlab-shell. -* `/home/git/gitlab` - GitLab core software. -* `/home/git/gitlab-satellites` - checked out repositories for merge requests and file editing from web UI. This can be treated as a temporary files directory. -* `/home/git/gitlab-shell` - Core add-on component of GitLab. Maintains SSH cloning and other functionality. -* `/home/git/repositories` - bare repositories for all projects organized by namespace. This is where the git repositories which are pushed/pulled are maintained for all projects. **This area is critical data for projects. [Keep a backup](../raketasks/backup_restore.md)** - -*Note: the default locations for gitlab-satellites and repositories can be configured in `config/gitlab.yml` of GitLab and `config.yml` of gitlab-shell.* - -To see a more in-depth overview see the [GitLab architecture doc](../development/architecture.md). diff --git a/doc/integration/README.md b/doc/integration/README.md deleted file mode 100644 index 286bd34a0bd57360c5376ef8ad3b700c397de125..0000000000000000000000000000000000000000 --- a/doc/integration/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# GitLab Integration - -GitLab integrates with multiple third-party services to allow external issue trackers and external authentication. - -See the documentation below for details on how to configure these services. - -- [External issue tracker](external-issue-tracker.md) Redmine, JIRA, etc. -- [LDAP](ldap.md) Set up sign in via LDAP -- [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab, and Google via OAuth. -- [Slack](slack.md) Integrate with the Slack chat service -- [OAuth2 provider](oauth_provider.md) OAuth2 application creation -- [Gmail](gitlab_buttons_in_gmail.md) Adds GitLab actions to messages - -GitLab Enterprise Edition contains [advanced JIRA support](http://doc.gitlab.com/ee/integration/jira.html) and [advanced Jenkins support](http://doc.gitlab.com/ee/integration/jenkins.html). - -## Project services - -Integration with services such as Campfire, Flowdock, Gemnasium, HipChat, Pivotal Tracker, and Slack are available in the form of a Project Service. -You can find these within GitLab in the Services page under Project Settings if you are at least a master on the project. -Project Services are a bit like plugins in that they allow a lot of freedom in adding functionality to GitLab, for example there is also a service that can send an email every time someone pushes new commits. -Because GitLab is open source we can ship with the code and tests for all plugins. -This allows the community to keep the plugins up to date so that they always work in newer GitLab versions. -For an overview of what projects services are available without logging in please see the [project_services directory](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/app/models/project_services). diff --git a/doc/integration/bitbucket.md b/doc/integration/bitbucket.md deleted file mode 100644 index d82e1f8b41ba02c89e8155099628b5fad30c144c..0000000000000000000000000000000000000000 --- a/doc/integration/bitbucket.md +++ /dev/null @@ -1,122 +0,0 @@ -# Integrate your server with Bitbucket - -Import projects from Bitbucket and login to your GitLab instance with your Bitbucket account. - -To enable the Bitbucket OmniAuth provider you must register your application with Bitbucket. -Bitbucket will generate an application ID and secret key for you to use. - -1. Sign in to Bitbucket. - -1. Navigate to your individual user settings or a team's settings, depending on how you want the application registered. It does not matter if the application is registered as an individual or a team - that is entirely up to you. - -1. Select "OAuth" in the left menu. - -1. Select "Add consumer". - -1. Provide the required details. - - Name: This can be anything. Consider something like "\'s GitLab" or "\'s GitLab" or something else descriptive. - - Application description: Fill this in if you wish. - - URL: The URL to your GitLab installation. 'https://gitlab.company.com' -1. Select "Save". - -1. You should now see a Key and Secret in the list of OAuth customers. - Keep this page open as you continue configuration. - -1. On your GitLab server, open the configuration file. - - For omnibus package: - - ```sh - sudo editor /etc/gitlab/gitlab.rb - ``` - - For instalations from source: - - ```sh - cd /home/git/gitlab - - sudo -u git -H editor config/gitlab.yml - ``` - -1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for initial settings. - -1. Add the provider configuration: - - For omnibus package: - - ```ruby - gitlab_rails['omniauth_providers'] = [ - { - "name" => "bitbucket", - "app_id" => "YOUR_KEY", - "app_secret" => "YOUR_APP_SECRET", - "url" => "https://bitbucket.org/" - } - ] - ``` - - For installation from source: - - ``` - - { name: 'bitbucket', app_id: 'YOUR_KEY', - app_secret: 'YOUR_APP_SECRET' } - ``` - -1. Change 'YOUR_APP_ID' to the key from the Bitbucket application page from step 7. - -1. Change 'YOUR_APP_SECRET' to the secret from the Bitbucket application page from step 7. - -1. Save the configuration file. - -1. Restart GitLab for the changes to take effect. - -On the sign in page there should now be a Bitbucket icon below the regular sign in form. -Click the icon to begin the authentication process. Bitbucket will ask the user to sign in and authorize the GitLab application. -If everything goes well the user will be returned to GitLab and will be signed in. - -## Bitbucket project import - -To allow projects to be imported directly into GitLab, Bitbucket requires two extra setup steps compared to GitHub and GitLab.com. - -Bitbucket doesn't allow OAuth applications to clone repositories over HTTPS, and instead requires GitLab to use SSH and identify itself using your GitLab server's SSH key. - -### Step 1: Known hosts - -To allow GitLab to connect to Bitbucket over SSH, you need to add 'bitbucket.org' to your GitLab server's known SSH hosts. Take the following steps to do so: - -1. Manually connect to 'bitbucket.org' over SSH, while logged in as the `git` account that GitLab will use: - - ```sh - ssh git@bitbucket.org - ``` - -1. Verify the RSA key fingerprint you'll see in the response matches the one in the [Bitbucket documentation](https://confluence.atlassian.com/display/BITBUCKET/Use+the+SSH+protocol+with+Bitbucket#UsetheSSHprotocolwithBitbucket-KnownhostorBitbucket'spublickeyfingerprints) (the specific IP address doesn't matter): - - ```sh - The authenticity of host 'bitbucket.org (207.223.240.182)' can't be established. - RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40. - Are you sure you want to continue connecting (yes/no)? - ``` - -1. If the fingerprint matches, type `yes` to continue connecting and have 'bitbucket.org' be added to your known hosts. - -1. Your GitLab server is now able to connect to Bitbucket over SSH. Continue to step 2: - -### Step 2: Public key - -To be able to access repositories on Bitbucket, GitLab will automatically register your public key with Bitbucket as a deploy key for the repositories to be imported. Your public key needs to be at `~/.ssh/bitbucket_rsa.pub`, which will expand to `/home/git/.ssh/bitbucket_rsa.pub` in most configurations. - -If you have that file in place, you're all set and should see the "Import projects from Bitbucket" option enabled. If you don't, do the following: - -1. Create a new SSH key: - - ```sh - sudo -u git -H ssh-keygen - ``` - - When asked `Enter file in which to save the key` specify the correct path, eg. `/home/git/.ssh/bitbucket_rsa`. - Make sure to use an **empty passphrase**. - -2. Restart GitLab to allow it to find the new public key. - -You should now see the "Import projects from Bitbucket" option on the New Project page enabled. diff --git a/doc/integration/external-issue-tracker.md b/doc/integration/external-issue-tracker.md deleted file mode 100644 index 96755707dee3d9e59c4f7c8b5cde373a092e9efb..0000000000000000000000000000000000000000 --- a/doc/integration/external-issue-tracker.md +++ /dev/null @@ -1,39 +0,0 @@ -# External issue tracker - -GitLab has a great issue tracker but you can also use an external issue tracker such as Jira, Bugzilla or Redmine. You can configure issue trackers per GitLab project. For instance, if you configure Jira it allows you to do the following: - -- the 'Issues' link on the GitLab project pages takes you to the appropriate Jira issue index; -- clicking 'New issue' on the project dashboard creates a new Jira issue; -- To reference Jira issue PROJECT-1234 in comments, use syntax PROJECT-1234. Commit messages get turned into HTML links to the corresponding Jira issue. - -![Jira screenshot](jira-integration-points.png) - -GitLab Enterprise Edition contains [advanced JIRA support](http://doc.gitlab.com/ee/integration/jira.html). - -## Configuration - -### Project Service - -You can enable an external issue tracker per project. As an example, we will configure `Redmine` for project named gitlab-ci. - -Fill in the required details on the page: - -![redmine configuration](redmine_configuration.png) - -* `description` A name for the issue tracker (to differentiate between instances, for example). -* `project_url` The URL to the project in Redmine which is being linked to this GitLab project. -* `issues_url` The URL to the issue in Redmine project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the url. This id is used by GitLab as a placeholder to replace the issue number. -* `new_issue_url` This is the URL to create a new issue in Redmine for the project linked to this GitLab project. - -### Service Template - -It is necessary to configure the external issue tracker per project, because project specific details are needed for the integration with GitLab. -The admin can add a service template that sets a default for each project. This makes it much easier to configure individual projects. - -In GitLab Admin section, navigate to `Service Templates` and choose the service template you want to create: - -![redmine service template](redmine_service_template.png) - -After the template is created, the template details will be pre-filled on the project service page. - -Support to add your commits to the Jira ticket automatically is [available in GitLab EE](http://doc.gitlab.com/ee/integration/jira.html). diff --git a/doc/integration/github.md b/doc/integration/github.md deleted file mode 100644 index b64501c2aaab8ec3f32c91c70426c158f69a4955..0000000000000000000000000000000000000000 --- a/doc/integration/github.md +++ /dev/null @@ -1,79 +0,0 @@ -# Integrate your server with GitHub - -Import projects from GitHub and login to your GitLab instance with your GitHub account. - -To enable the GitHub OmniAuth provider you must register your application with GitHub. -GitHub will generate an application ID and secret key for you to use. - -1. Sign in to GitHub. - -1. Navigate to your individual user settings or an organization's settings, depending on how you want the application registered. It does not matter if the application is registered as an individual or an organization - that is entirely up to you. - -1. Select "Applications" in the left menu. - -1. Select "Register new application". - -1. Provide the required details. - - Application name: This can be anything. Consider something like "\'s GitLab" or "\'s GitLab" or something else descriptive. - - Homepage URL: The URL to your GitLab installation. 'https://gitlab.company.com' - - Application description: Fill this in if you wish. - - Authorization callback URL: 'https://gitlab.company.com/' -1. Select "Register application". - -1. You should now see a Client ID and Client Secret near the top right of the page (see screenshot). - Keep this page open as you continue configuration. - ![GitHub app](github_app.png) - -1. On your GitLab server, open the configuration file. - - For omnibus package: - - ```sh - sudo editor /etc/gitlab/gitlab.rb - ``` - - For instalations from source: - - ```sh - cd /home/git/gitlab - - sudo -u git -H editor config/gitlab.yml - ``` - -1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for initial settings. - -1. Add the provider configuration: - - For omnibus package: - - ```ruby - gitlab_rails['omniauth_providers'] = [ - { - "name" => "github", - "app_id" => "YOUR_APP_ID", - "app_secret" => "YOUR_APP_SECRET", - "url" => "https://github.com/", - "args" => { "scope" => "user:email" } - } - ] - ``` - - For installation from source: - - ``` - - { name: 'github', app_id: 'YOUR_APP_ID', - app_secret: 'YOUR_APP_SECRET', - args: { scope: 'user:email' } } - ``` - -1. Change 'YOUR_APP_ID' to the client ID from the GitHub application page from step 7. - -1. Change 'YOUR_APP_SECRET' to the client secret from the GitHub application page from step 7. - -1. Save the configuration file. - -1. Restart GitLab for the changes to take effect. - -On the sign in page there should now be a GitHub icon below the regular sign in form. -Click the icon to begin the authentication process. GitHub will ask the user to sign in and authorize the GitLab application. -If everything goes well the user will be returned to GitLab and will be signed in. diff --git a/doc/integration/github_app.png b/doc/integration/github_app.png deleted file mode 100644 index d890345ced917f2c78ae77dc39c2b66d1362e0d5..0000000000000000000000000000000000000000 Binary files a/doc/integration/github_app.png and /dev/null differ diff --git a/doc/integration/gitlab.md b/doc/integration/gitlab.md deleted file mode 100644 index 216f1f11a9b0c9b1d9c364305364f0f0216cab8a..0000000000000000000000000000000000000000 --- a/doc/integration/gitlab.md +++ /dev/null @@ -1,84 +0,0 @@ -# Integrate your server with GitLab.com - -Import projects from GitLab.com and login to your GitLab instance with your GitLab.com account. - -To enable the GitLab.com OmniAuth provider you must register your application with GitLab.com. -GitLab.com will generate an application ID and secret key for you to use. - -1. Sign in to GitLab.com - -1. Navigate to your profile settings. - -1. Select "Applications" in the left menu. - -1. Select "New application". - -1. Provide the required details. - - Name: This can be anything. Consider something like "\'s GitLab" or "\'s GitLab" or something else descriptive. - - Redirect URI: - - ``` - http://your-gitlab.example.com/import/gitlab/callback - http://your-gitlab.example.com/users/auth/gitlab/callback - ``` - - The first link is required for the importer and second for the authorization. - -1. Select "Submit". - -1. You should now see a Client ID and Client Secret near the top right of the page (see screenshot). - Keep this page open as you continue configuration. - ![GitLab app](gitlab_app.png) - -1. On your GitLab server, open the configuration file. - - For omnibus package: - - ```sh - sudo editor /etc/gitlab/gitlab.rb - ``` - - For instalations from source: - - ```sh - cd /home/git/gitlab - - sudo -u git -H editor config/gitlab.yml - ``` - -1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for initial settings. - -1. Add the provider configuration: - - For omnibus package: - - ```ruby - gitlab_rails['omniauth_providers'] = [ - { - "name" => "gitlab", - "app_id" => "YOUR_APP_ID", - "app_secret" => "YOUR_APP_SECRET", - "args" => { "scope" => "api" } - } - ] - ``` - - For installations from source: - - ``` - - { name: 'gitlab', app_id: 'YOUR_APP_ID', - app_secret: 'YOUR_APP_SECRET', - args: { scope: 'api' } } - ``` - -1. Change 'YOUR_APP_ID' to the Application ID from the GitLab.com application page. - -1. Change 'YOUR_APP_SECRET' to the secret from the GitLab.com application page. - -1. Save the configuration file. - -1. Restart GitLab for the changes to take effect. - -On the sign in page there should now be a GitLab.com icon below the regular sign in form. -Click the icon to begin the authentication process. GitLab.com will ask the user to sign in and authorize the GitLab application. -If everything goes well the user will be returned to your GitLab instance and will be signed in. diff --git a/doc/integration/gitlab_actions.png b/doc/integration/gitlab_actions.png deleted file mode 100644 index b08f54d137bd9ab1bde8471211f95016a9ee6aa0..0000000000000000000000000000000000000000 Binary files a/doc/integration/gitlab_actions.png and /dev/null differ diff --git a/doc/integration/gitlab_app.png b/doc/integration/gitlab_app.png deleted file mode 100644 index 3f9391a821bcb2d625e4c8e4db10f1da66168240..0000000000000000000000000000000000000000 Binary files a/doc/integration/gitlab_app.png and /dev/null differ diff --git a/doc/integration/gitlab_buttons_in_gmail.md b/doc/integration/gitlab_buttons_in_gmail.md deleted file mode 100644 index a9885cef1092ce710ffb7981dd7c810b11329903..0000000000000000000000000000000000000000 --- a/doc/integration/gitlab_buttons_in_gmail.md +++ /dev/null @@ -1,28 +0,0 @@ -# GitLab buttons in Gmail - -GitLab supports [Google actions in email](https://developers.google.com/gmail/markup/actions/actions-overview). - -If correctly setup, emails that require an action will be marked in Gmail. - -![gitlab_actions](gitlab_actions.png) - -To get this functioning, you need to be registered with Google. -[See how to register with google in this document.](https://developers.google.com/gmail/markup/registering-with-google) - -To aid the registering with google, GitLab offers a rake task that will send an email to google whitelisting email address from your GitLab server. - -To check what would be sent to the google email address, run the rake task: - -```bash -bundle exec rake gitlab:mail_google_schema_whitelisting RAILS_ENV=production -``` - -**This will not send the email but give you the output of how the mail will look.** - -Copy the output of the rake task to [google email markup tester](https://www.google.com/webmasters/markup-tester/u/0/) and press "Validate". - -If you receive "No errors detected" message from the tester you can send the email using: - -```bash -bundle exec rake gitlab:mail_google_schema_whitelisting RAILS_ENV=production SEND=true -``` diff --git a/doc/integration/google.md b/doc/integration/google.md deleted file mode 100644 index e1c14c7c94828f08b04254a7427f65b18b809a38..0000000000000000000000000000000000000000 --- a/doc/integration/google.md +++ /dev/null @@ -1,89 +0,0 @@ -# Google OAuth2 OmniAuth Provider - -To enable the Google OAuth2 OmniAuth provider you must register your application with Google. Google will generate a client ID and secret key for you to use. - -1. Sign in to the [Google Developers Console](https://console.developers.google.com/) with the Google account you want to use to register GitLab. - -1. Select "Create Project". - -1. Provide the project information - - Project name: 'GitLab' works just fine here. - - Project ID: Must be unique to all Google Developer registered applications. Google provides a randomly generated Project ID by default. You can use the randomly generated ID or choose a new one. -1. Refresh the page. You should now see your new project in the list. Click on the project. - -1. Select "APIs & auth" in the left menu. - -1. Select "APIs" in the submenu. - - Enable `Contacts API` - - Enable `Google+ API` - -1. Select "Credentials" in the submenu. - -1. Select "Create New Client ID". - -1. Fill in the required information - - Application type: "Web Application" - - Authorized JavaScript origins: This isn't really used by GitLab but go ahead and put 'https://gitlab.example.com' here. - - Authorized redirect URI: 'https://gitlab.example.com/users/auth/google_oauth2/callback' -1. Under the heading "Client ID for web application" you should see a Client ID and Client secret (see screenshot). Keep this page open as you continue configuration. ![Google app](google_app.png) - -1. On your GitLab server, open the configuration file. - - For omnibus package: - - ```sh - sudo editor /etc/gitlab/gitlab.rb - ``` - - For instalations from source: - - ```sh - cd /home/git/gitlab - - sudo -u git -H editor config/gitlab.yml - ``` - -1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for initial settings. - -1. Add the provider configuration: - - For omnibus package: - - ```ruby - gitlab_rails['omniauth_providers'] = [ - { - "name" => "google_oauth2", - "app_id" => "YOUR_APP_ID", - "app_secret" => "YOUR_APP_SECRET", - "args" => { "access_type" => "offline", "approval_prompt" => '' } - } - ] - ``` - - For installations from source: - - ``` - - { name: 'google_oauth2', app_id: 'YOUR_APP_ID', - app_secret: 'YOUR_APP_SECRET', - args: { access_type: 'offline', approval_prompt: '' } } - ``` - -1. Change 'YOUR_APP_ID' to the client ID from the Google Developer page from step 10. - -1. Change 'YOUR_APP_SECRET' to the client secret from the Google Developer page from step 10. - -1. Save the configuration file. - -1. Restart GitLab for the changes to take effect. - -On the sign in page there should now be a Google icon below the regular sign in form. Click the icon to begin the authentication process. Google will ask the user to sign in and authorize the GitLab application. If everything goes well the user will be returned to GitLab and will be signed in. - -## Further Configuration - -This further configuration is not required for Google authentication to function but it is strongly recommended. Taking these steps will increase usability for users by providing a little more recognition and branding. - -At this point, when users first try to authenticate to your GitLab installation with Google they will see a generic application name on the prompt screen. The prompt informs the user that "Project Default Service Account" would like to access their account. "Project Default Service Account" isn't very recognizable and may confuse or cause users to be concerned. This is easily changeable. - -1. Select 'Consent screen' in the left menu. (See steps 1, 4 and 5 above for instructions on how to get here if you closed your window). -1. Scroll down until you find "Product Name". Change the product name to something more descriptive. -1. Add any additional information as you wish - homepage, logo, privacy policy, etc. None of this is required, but it may help your users. diff --git a/doc/integration/google_app.png b/doc/integration/google_app.png deleted file mode 100644 index 5a62ad35009bc7786600408837f96b5c9ed97a07..0000000000000000000000000000000000000000 Binary files a/doc/integration/google_app.png and /dev/null differ diff --git a/doc/integration/jira-integration-points.png b/doc/integration/jira-integration-points.png deleted file mode 100644 index 0692a7b458a3eef7486c0c665b16eb4222cfd11a..0000000000000000000000000000000000000000 Binary files a/doc/integration/jira-integration-points.png and /dev/null differ diff --git a/doc/integration/ldap.md b/doc/integration/ldap.md deleted file mode 100644 index b67f793c59106763d5f95315c7a57f6ac88ab004..0000000000000000000000000000000000000000 --- a/doc/integration/ldap.md +++ /dev/null @@ -1,148 +0,0 @@ -# GitLab LDAP integration - -GitLab can be configured to allow your users to sign with their LDAP credentials to integrate with e.g. Active Directory. - -The first time a user signs in with LDAP credentials, GitLab will create a new GitLab user associated with the LDAP Distinguished Name (DN) of the LDAP user. - -GitLab user attributes such as nickname and email will be copied from the LDAP user entry. - -## Configuring GitLab for LDAP integration - -To enable GitLab LDAP integration you need to add your LDAP server settings in `/etc/gitlab/gitlab.rb` or `/home/git/gitlab/config/gitlab.yml`. -In GitLab Enterprise Edition you can have multiple LDAP servers connected to one GitLab server. - -Please note that before version 7.4, GitLab used a different syntax for configuring LDAP integration. -The old LDAP integration syntax still works in GitLab 7.4. -If your `gitlab.rb` or `gitlab.yml` file contains LDAP settings in both the old syntax and the new syntax, only the __old__ syntax will be used by GitLab. - -```ruby -# For omnibus packages -gitlab_rails['ldap_enabled'] = true -gitlab_rails['ldap_servers'] = YAML.load <<-EOS # remember to close this block with 'EOS' below -main: # 'main' is the GitLab 'provider ID' of this LDAP server - ## label - # - # A human-friendly name for your LDAP server. It is OK to change the label later, - # for instance if you find out it is too large to fit on the web page. - # - # Example: 'Paris' or 'Acme, Ltd.' - label: 'LDAP' - - host: '_your_ldap_server' - port: 389 - uid: 'sAMAccountName' - method: 'plain' # "tls" or "ssl" or "plain" - bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' - password: '_the_password_of_the_bind_user' - - # This setting specifies if LDAP server is Active Directory LDAP server. - # For non AD servers it skips the AD specific queries. - # If your LDAP server is not AD, set this to false. - active_directory: true - - # If allow_username_or_email_login is enabled, GitLab will ignore everything - # after the first '@' in the LDAP username submitted by the user on login. - # - # Example: - # - the user enters 'jane.doe@example.com' and 'p@ssw0rd' as LDAP credentials; - # - GitLab queries the LDAP server with 'jane.doe' and 'p@ssw0rd'. - # - # If you are using "uid: 'userPrincipalName'" on ActiveDirectory you need to - # disable this setting, because the userPrincipalName contains an '@'. - allow_username_or_email_login: false - - # To maintain tight control over the number of active users on your GitLab installation, - # enable this setting to keep new users blocked until they have been cleared by the admin - # (default: false). - block_auto_created_users: false - - # Base where we can search for users - # - # Ex. ou=People,dc=gitlab,dc=example - # - base: '' - - # Filter LDAP users - # - # Format: RFC 4515 http://tools.ietf.org/search/rfc4515 - # Ex. (employeeType=developer) - # - # Note: GitLab does not support omniauth-ldap's custom filter syntax. - # - user_filter: '' - -# GitLab EE only: add more LDAP servers -# Choose an ID made of a-z and 0-9 . This ID will be stored in the database -# so that GitLab can remember which LDAP server a user belongs to. -# uswest2: -# label: -# host: -# .... -EOS -``` - -If you are getting 'Connection Refused' errors when trying to connect to the LDAP server please double-check the LDAP `port` and `method` settings used by GitLab. -Common combinations are `method: 'plain'` and `port: 389`, OR `method: 'ssl'` and `port: 636`. - -If you are using a GitLab installation from source you can find the LDAP settings in `/home/git/gitlab/config/gitlab.yml`: - -``` -production: - # snip... - ldap: - enabled: false - servers: - main: # 'main' is the GitLab 'provider ID' of this LDAP server - ## label - # - # A human-friendly name for your LDAP server. It is OK to change the label later, - # for instance if you find out it is too large to fit on the web page. - # - # Example: 'Paris' or 'Acme, Ltd.' - label: 'LDAP' - # snip... -``` - -## Enabling LDAP sign-in for existing GitLab users - -When a user signs in to GitLab with LDAP for the first time, and their LDAP email address is the primary email address of an existing GitLab user, then the LDAP DN will be associated with the existing user. - -If the LDAP email attribute is not found in GitLab's database, a new user is created. - -In other words, if an existing GitLab user wants to enable LDAP sign-in for themselves, they should check that their GitLab email address matches their LDAP email address, and then sign into GitLab via their LDAP credentials. - -GitLab recognizes the following LDAP attributes as email addresses: `mail`, `email` and `userPrincipalName`. - -If multiple LDAP email attributes are present, e.g. `mail: foo@bar.com` and `email: foo@example.com`, then the first attribute found wins -- in this case `foo@bar.com`. - -## Using an LDAP filter to limit access to your GitLab server - -If you want to limit all GitLab access to a subset of the LDAP users on your LDAP server you can set up an LDAP user filter. -The filter must comply with [RFC 4515](http://tools.ietf.org/search/rfc4515). - -```ruby -# For omnibus packages; new LDAP server syntax -gitlab_rails['ldap_servers'] = YAML.load <<-EOS -main: - # snip... - user_filter: '(employeeType=developer)' -EOS -``` - -```yaml -# For installations from source; new LDAP server syntax -production: - ldap: - servers: - main: - # snip... - user_filter: '(employeeType=developer)' -``` - -Tip: if you want to limit access to the nested members of an Active Directory group you can use the following syntax: - -``` -(memberOf:1.2.840.113556.1.4.1941:=CN=My Group,DC=Example,DC=com) -``` - -Please note that GitLab does not support the custom filter syntax used by omniauth-ldap. diff --git a/doc/integration/oauth_provider.md b/doc/integration/oauth_provider.md deleted file mode 100644 index 192c321f7129941e44c68b23e8257c36e8da4ee2..0000000000000000000000000000000000000000 --- a/doc/integration/oauth_provider.md +++ /dev/null @@ -1,35 +0,0 @@ -## GitLab as OAuth2 authentication service provider - -This document is about using GitLab as an OAuth authentication service provider to sign into other services. -If you want to use other OAuth authentication service providers to sign into GitLab please see the [OAuth2 client documentation](../api/oauth2.md) - -OAuth2 provides client applications a 'secure delegated access' to server resources on behalf of a resource owner. Or you can allow users to sign in to your application with their GitLab.com account. -In fact OAuth allows to issue access token to third-party clients by an authorization server, -with the approval of the resource owner, or end-user. -Mostly, OAuth2 is using for SSO (Single sign-on). But you can find a lot of different usages for this functionality. -For example, our feature 'GitLab Importer' is using OAuth protocol to give an access to repositories without sharing user credentials to GitLab.com account. -Also GitLab.com application can be used for authentication to your GitLab instance if needed [GitLab OmniAuth](gitlab.md). - -GitLab has two ways to add new OAuth2 application to an instance, you can add application as regular user and through admin area. So GitLab actually can have an instance-wide and a user-wide applications. There is no defferences between them except the different permission levels. - -### Adding application through profile -Go to your profile section 'Application' and press button 'New Application' - -![applications](oauth_provider/user_wide_applications.png) - -After this you will see application form, where "Name" is arbitrary name, "Redirect URI" is URL in your app where users will be sent after authorization on GitLab.com. - -![application_form](oauth_provider/application_form.png) - -### Authorized application -Every application you authorized will be shown in your "Authorized application" sections. - -![authorized_application](oauth_provider/authorized_application.png) - -At any time you can revoke access just clicking button "Revoke" - -### OAuth applications in admin area - -If you want to create application that does not belong to certain user you can create it from admin area - -![admin_application](oauth_provider/admin_application.png) \ No newline at end of file diff --git a/doc/integration/oauth_provider/admin_application.png b/doc/integration/oauth_provider/admin_application.png deleted file mode 100644 index a5f34512aa85236ac9ecc7d70129d8a3a3f1a71b..0000000000000000000000000000000000000000 Binary files a/doc/integration/oauth_provider/admin_application.png and /dev/null differ diff --git a/doc/integration/oauth_provider/application_form.png b/doc/integration/oauth_provider/application_form.png deleted file mode 100644 index ae135db2627f24b24e4b4b1ba401ab78e2de0b09..0000000000000000000000000000000000000000 Binary files a/doc/integration/oauth_provider/application_form.png and /dev/null differ diff --git a/doc/integration/oauth_provider/authorized_application.png b/doc/integration/oauth_provider/authorized_application.png deleted file mode 100644 index d3ce05be9cc71cf965a8941313057f6d0851b085..0000000000000000000000000000000000000000 Binary files a/doc/integration/oauth_provider/authorized_application.png and /dev/null differ diff --git a/doc/integration/oauth_provider/user_wide_applications.png b/doc/integration/oauth_provider/user_wide_applications.png deleted file mode 100644 index 719e1974068eaf081fbaea3c0b397654a56f9379..0000000000000000000000000000000000000000 Binary files a/doc/integration/oauth_provider/user_wide_applications.png and /dev/null differ diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md deleted file mode 100644 index 24f7b4bb4b407a2770f0d5735dea87a649ea1983..0000000000000000000000000000000000000000 --- a/doc/integration/omniauth.md +++ /dev/null @@ -1,127 +0,0 @@ -# OmniAuth - -GitLab leverages OmniAuth to allow users to sign in using Twitter, GitHub, and other popular services. - -Configuring OmniAuth does not prevent standard GitLab authentication or LDAP (if configured) from continuing to work. Users can choose to sign in using any of the configured mechanisms. - -- [Initial OmniAuth Configuration](#initial-omniauth-configuration) -- [Supported Providers](#supported-providers) -- [Enable OmniAuth for an Existing User](#enable-omniauth-for-an-existing-user) -- [OmniAuth configuration sample when using Omnibus GitLab](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master#omniauth-google-twitter-github-login) - -## Initial OmniAuth Configuration - -Before configuring individual OmniAuth providers there are a few global settings that are in common for all providers that we need to consider. - -- Omniauth needs to be enabled, see details below for example. -- `allow_single_sign_on` defaults to `false`. If `false` users must be created manually or they will not be able to -sign in via OmniAuth. -- `block_auto_created_users` defaults to `true`. If `true` auto created users will be blocked by default and will -have to be unblocked by an administrator before they are able to sign in. -- **Note:** If you set `allow_single_sign_on` to `true` and `block_auto_created_users` to `false` please be aware -that any user on the Internet will be able to successfully sign in to your GitLab without administrative approval. - -If you want to change these settings: - -* **For omnibus package** - - Open the configuration file: - - ```sh - sudo editor /etc/gitlab/gitlab.rb - ``` - - and change - - ``` - gitlab_rails['omniauth_enabled'] = true - gitlab_rails['omniauth_allow_single_sign_on'] = false - gitlab_rails['block_auto_created_users'] = true - ``` - -* **For installations from source** - - Open the configuration file: - - ```sh - cd /home/git/gitlab - - sudo -u git -H editor config/gitlab.yml - ``` - - and change the following section - - ``` - ## OmniAuth settings - omniauth: - # Allow login via Twitter, Google, etc. using OmniAuth providers - enabled: true - - # CAUTION! - # This allows users to login without having a user account first (default: false). - # User accounts will be created automatically when authentication was successful. - allow_single_sign_on: false - # Locks down those users until they have been cleared by the admin (default: true). - block_auto_created_users: true - ``` - -Now we can choose one or more of the Supported Providers below to continue configuration. - -## Supported Providers - -- [GitHub](github.md) -- [Bitbucket](bitbucket.md) -- [GitLab.com](gitlab.md) -- [Google](google.md) -- [Shibboleth](shibboleth.md) -- [Twitter](twitter.md) - -## Enable OmniAuth for an Existing User - -Existing users can enable OmniAuth for specific providers after the account is created. For example, if the user originally signed in with LDAP an OmniAuth provider such as Twitter can be enabled. Follow the steps below to enable an OmniAuth provider for an existing user. - -1. Sign in normally - whether standard sign in, LDAP, or another OmniAuth provider. -1. Go to profile settings (the silhouette icon in the top right corner). -1. Select the "Account" tab. -1. Under "Social Accounts" select the desired OmniAuth provider, such as Twitter. -1. The user will be redirected to the provider. Once the user authorized GitLab they will be redirected back to GitLab. - -The chosen OmniAuth provider is now active and can be used to sign in to GitLab from then on. - -## Using Custom Omniauth Providers - -GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already ships with a few providers preinstalled (e.g. LDAP, GitHub, Twitter). But sometimes that is not enough and you need to integrate with other authentication solutions. For these cases you can use the Omniauth provider. - -### Steps - -These steps are fairly general and you will need to figure out the exact details from the Omniauth provider's documentation. - -- Stop GitLab: - - sudo service gitlab stop - -- Add the gem to your [Gemfile](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/Gemfile): - - gem "omniauth-your-auth-provider" - -- If you're using MySQL, install the new Omniauth provider gem by running the following command: - - sudo -u git -H bundle install --without development test postgres --path vendor/bundle --no-deployment - -- If you're using PostgreSQL, install the new Omniauth provider gem by running the following command: - - sudo -u git -H bundle install --without development test mysql --path vendor/bundle --no-deployment - - > These are the same commands you used in the [Install Gems section](#install-gems) with `--path vendor/bundle --no-deployment` instead of `--deployment`. - -- Start GitLab: - - sudo service gitlab start - -### Examples - -If you have successfully set up a provider that is not shipped with GitLab itself, please let us know. - -You can help others by reporting successful configurations and probably share a few insights or provide warnings for common errors or pitfalls by sharing your experience [in the public Wiki](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Custom-omniauth-provider-configurations). - -While we can't officially support every possible authentication mechanism out there, we'd like to at least help those with specific needs. diff --git a/doc/integration/redmine_configuration.png b/doc/integration/redmine_configuration.png deleted file mode 100644 index 6b1453632293f010e2349a98270e99d5ac60c39d..0000000000000000000000000000000000000000 Binary files a/doc/integration/redmine_configuration.png and /dev/null differ diff --git a/doc/integration/redmine_service_template.png b/doc/integration/redmine_service_template.png deleted file mode 100644 index 1159eb5b9649f1efdd513e224931731bea99fbd3..0000000000000000000000000000000000000000 Binary files a/doc/integration/redmine_service_template.png and /dev/null differ diff --git a/doc/integration/shibboleth.md b/doc/integration/shibboleth.md deleted file mode 100644 index 6258e5f1030980980b9188cebb2d2c2031fc554a..0000000000000000000000000000000000000000 --- a/doc/integration/shibboleth.md +++ /dev/null @@ -1,78 +0,0 @@ -# Shibboleth OmniAuth Provider - -This documentation is for enabling shibboleth with gitlab-omnibus package. - -In order to enable Shibboleth support in gitlab we need to use Apache instead of Nginx (It may be possible to use Nginx, however I did not found way to easily configure Nginx that is bundled in gitlab-omnibus package). Apache uses mod_shib2 module for shibboleth authentication and can pass attributes as headers to omniauth-shibboleth provider. - - -To enable the Shibboleth OmniAuth provider you must: - -1. Configure Apache shibboleth module. Installation and configuration of module it self is out of scope of this document. -Check https://wiki.shibboleth.net/ for more info. - -1. You can find Apache config in gitlab-recipes (https://github.com/gitlabhq/gitlab-recipes/blob/master/web-server/apache/gitlab-ssl.conf) - -Following changes are needed to enable shibboleth: - -protect omniauth-shibboleth callback URL: -``` - - AuthType shibboleth - ShibRequestSetting requireSession 1 - ShibUseHeaders On - require valid-user - - - Alias /shibboleth-sp /usr/share/shibboleth - - Satisfy any - - - - SetHandler shib - -``` -exclude shibboleth URLs from rewriting, add "RewriteCond %{REQUEST_URI} !/Shibboleth.sso" and "RewriteCond %{REQUEST_URI} !/shibboleth-sp", config should look like this: -``` - # Apache equivalent of Nginx try files - RewriteEngine on - RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_URI} !/Shibboleth.sso - RewriteCond %{REQUEST_URI} !/shibboleth-sp - RewriteRule .* http://127.0.0.1:8080%{REQUEST_URI} [P,QSA] - RequestHeader set X_FORWARDED_PROTO 'https' -``` - -1. Edit /etc/gitlab/gitlab.rb configuration file, your shibboleth attributes should be in form of "HTTP_ATTRIBUTE" and you should addjust them to your need and environment. Add any other configuration you need. - -File should look like this: -``` -external_url 'https://gitlab.example.com' -gitlab_rails['internal_api_url'] = 'https://gitlab.example.com' - -# disable Nginx -nginx['enable'] = false - -gitlab_rails['omniauth_allow_single_sign_on'] = true -gitlab_rails['omniauth_block_auto_created_users'] = false -gitlab_rails['omniauth_enabled'] = true -gitlab_rails['omniauth_providers'] = [ - { - "name" => 'shibboleth', - "args" => { - "shib_session_id_field" => "HTTP_SHIB_SESSION_ID", - "shib_application_id_field" => "HTTP_SHIB_APPLICATION_ID", - "uid_field" => 'HTTP_EPPN', - "name_field" => 'HTTP_CN', - "info_fields" => { "email" => 'HTTP_MAIL'} - } - } -] - -``` -1. Save changes and reconfigure gitlab: -``` -sudo gitlab-ctl reconfigure -``` - -On the sign in page there should now be a "Sign in with: Shibboleth" icon below the regular sign in form. Click the icon to begin the authentication process. You will be redirected to IdP server (Depends on your Shibboleth module configuration). If everything goes well the user will be returned to GitLab and will be signed in. diff --git a/doc/integration/slack.md b/doc/integration/slack.md deleted file mode 100644 index 2fd22c513ad4b84d1420baa2326611e067c3af29..0000000000000000000000000000000000000000 --- a/doc/integration/slack.md +++ /dev/null @@ -1,42 +0,0 @@ -# Slack integration - -## On Slack - -To enable Slack integration you must create an Incoming WebHooks integration on Slack; - -1. [Sign in to Slack](https://slack.com/signin) - -1. Select **Configure Integrations** from the dropdown next to your team name. - -1. Select the **All Services** tab - -1. Click **Add** next to Incoming Webhooks - -1. Pick Incoming WebHooks - -1. Choose the channel name you want to send notifications to - -1. Click **Add Incoming WebHooks Integration**Add Integrations. - - Optional step; You can change bot's name and avatar by clicking modifying the bot name or avatar under **Integration Settings**. - -1. Copy the **Webhook URL**, we'll need this later for GitLab. - - -## On GitLab - -After Slack is ready we need to setup GitLab. Here are the steps to achieve this. - -1. Sign in to GitLab - -1. Pick the repository you want. - -1. Navigate to Settings -> Services -> Slack - -1. Fill in your Slack details - - - Mark it as active - - Paste in the webhook URL you got from Slack - -Have fun :) - -*P.S. You can set "branch,pushed,Compare changes" as highlight words on your Slack profile settings, so that you can be aware of new commits when somebody pushes them.* diff --git a/doc/integration/twitter.md b/doc/integration/twitter.md deleted file mode 100644 index fe9091ad9a8393640485a2d1291a3eb92562760f..0000000000000000000000000000000000000000 --- a/doc/integration/twitter.md +++ /dev/null @@ -1,81 +0,0 @@ -# Twitter OAuth2 OmniAuth Provider - -To enable the Twitter OmniAuth provider you must register your application with Twitter. Twitter will generate a client ID and secret key for you to use. - -1. Sign in to [Twitter Developers](https://dev.twitter.com/) area. - -1. Hover over the avatar in the top right corner and select "My applications." - -1. Select "Create new app" - -1. Fill in the application details. - - Name: This can be anything. Consider something like "\'s GitLab" or "\'s GitLab" or - something else descriptive. - - Description: Create a description. - - Website: The URL to your GitLab installation. 'https://gitlab.example.com' - - Callback URL: 'https://gitlab.example.com/users/auth/twitter/callback' - - Agree to the "Rules of the Road." - - ![Twitter App Details](twitter_app_details.png) -1. Select "Create your Twitter application." - -1. Select the "Settings" tab. - -1. Underneath the Callback URL check the box next to "Allow this application to be used to Sign in the Twitter." - -1. Select "Update settings" at the bottom to save changes. - -1. Select the "API Keys" tab. - -1. You should now see an API key and API secret (see screenshot). Keep this page open as you continue configuration. - - ![Twitter app](twitter_app_api_keys.png) - -1. On your GitLab server, open the configuration file. - - For omnibus package: - - ```sh - sudo editor /etc/gitlab/gitlab.rb - ``` - - For instalations from source: - - ```sh - cd /home/git/gitlab - - sudo -u git -H editor config/gitlab.yml - ``` - -1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for initial settings. - -1. Add the provider configuration: - - For omnibus package: - - ```ruby - gitlab_rails['omniauth_providers'] = [ - { - "name" => "twitter", - "app_id" => "YOUR_APP_ID", - "app_secret" => "YOUR_APP_SECRET" - } - ] - ``` - - For installations from source: - - ``` - - { name: 'twitter', app_id: 'YOUR_APP_ID', - app_secret: 'YOUR_APP_SECRET' } - ``` - -1. Change 'YOUR_APP_ID' to the API key from Twitter page in step 11. - -1. Change 'YOUR_APP_SECRET' to the API secret from the Twitter page in step 11. - -1. Save the configuration file. - -1. Restart GitLab for the changes to take effect. - -On the sign in page there should now be a Twitter icon below the regular sign in form. Click the icon to begin the authentication process. Twitter will ask the user to sign in and authorize the GitLab application. If everything goes well the user will be returned to GitLab and will be signed in. diff --git a/doc/integration/twitter_app_api_keys.png b/doc/integration/twitter_app_api_keys.png deleted file mode 100644 index 1076337172a98c81c09a851ef0f4dc4fbfd0c006..0000000000000000000000000000000000000000 Binary files a/doc/integration/twitter_app_api_keys.png and /dev/null differ diff --git a/doc/integration/twitter_app_details.png b/doc/integration/twitter_app_details.png deleted file mode 100644 index b95e8af8a74eb7e7a9455d7ef9fafdf339a9627f..0000000000000000000000000000000000000000 Binary files a/doc/integration/twitter_app_details.png and /dev/null differ diff --git a/doc/legal/README.md b/doc/legal/README.md deleted file mode 100644 index 56d72ae3859d28301c7fa4ef3b9a04a263cc8fe6..0000000000000000000000000000000000000000 --- a/doc/legal/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Legal - -- [Corporate contributor license agreement](corporate_contributor_license_agreement.md) -- [Individual contributor license agreement](individual_contributor_license_agreement.md) diff --git a/doc/legal/corporate_contributor_license_agreement.md b/doc/legal/corporate_contributor_license_agreement.md deleted file mode 100644 index 13bf15fcf45c0c7b260d022aa0f1f6d6b02e2480..0000000000000000000000000000000000000000 --- a/doc/legal/corporate_contributor_license_agreement.md +++ /dev/null @@ -1,25 +0,0 @@ -# Corporate contributor license agreement - -You accept and agree to the following terms and conditions for Your present and future Contributions submitted to GitLab B.V.. Except for the license granted herein to GitLab B.V. and recipients of software distributed by GitLab B.V., You reserve all right, title, and interest in and to Your Contributions. - -1. Definitions. - - "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with GitLab B.V.. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - "Contribution" shall mean the code, documentation or other original works of authorship expressly identified in Schedule B, as well as any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to GitLab B.V. for inclusion in, or documentation of, any of the products owned or managed by GitLab B.V. (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to GitLab B.V. or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, GitLab B.V. for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution." - -2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to GitLab B.V. and to recipients of software distributed by GitLab B.V. a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works. - -3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to GitLab B.V. and to recipients of software distributed by GitLab B.V. a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed. - -4. You represent that You are legally entitled to grant the above license. You represent further that each employee of the Corporation designated on Schedule A below (or in a subsequent written modification to that Schedule) is authorized to submit Contributions on behalf of the Corporation. - -5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). - -6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. - -7. Should You wish to submit work that is not Your original creation, You may submit it to GitLab B.V. separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [named here]". - -8. It is your responsibility to notify GitLab B.V. when any change is required to the list of designated employees authorized to submit Contributions on behalf of the Corporation, or to the Corporation's Point of Contact with GitLab B.V.. - -This text is licensed under the [Creative Commons Attribution 3.0 License](http://creativecommons.org/licenses/by/3.0/) and the original source is the Google Open Source Programs Office. diff --git a/doc/legal/individual_contributor_license_agreement.md b/doc/legal/individual_contributor_license_agreement.md deleted file mode 100644 index 72b01433dd012433f46966ebc679f551283daafd..0000000000000000000000000000000000000000 --- a/doc/legal/individual_contributor_license_agreement.md +++ /dev/null @@ -1,25 +0,0 @@ -# Individual contributor license agreement - -You accept and agree to the following terms and conditions for Your present and future Contributions submitted to GitLab B.V.. Except for the license granted herein to GitLab B.V. and recipients of software distributed by GitLab B.V., You reserve all right, title, and interest in and to Your Contributions. - -1. Definitions. - - "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with GitLab B.V.. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - - "Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to GitLab B.V. for inclusion in, or documentation of, any of the products owned or managed by GitLab B.V. (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to GitLab B.V. or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, GitLab B.V. for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution." - -2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to GitLab B.V. and to recipients of software distributed by GitLab B.V. a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works. - -3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to GitLab B.V. and to recipients of software distributed by GitLab B.V. a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed. - -4. You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to GitLab B.V., or that your employer has executed a separate Corporate CLA with GitLab B.V.. - -5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions. - -6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. - -7. Should You wish to submit work that is not Your original creation, You may submit it to GitLab B.V. separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [[]named here]". - -8. You agree to notify GitLab B.V. of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect. - -This text is licensed under the [Creative Commons Attribution 3.0 License](http://creativecommons.org/licenses/by/3.0/) and the original source is the Google Open Source Programs Office. diff --git a/doc/logs/logs.md b/doc/logs/logs.md deleted file mode 100644 index ec0109a426f427a5ea92621d69bd46899b700f59..0000000000000000000000000000000000000000 --- a/doc/logs/logs.md +++ /dev/null @@ -1,102 +0,0 @@ -## Log system -GitLab has advanced log system so everything is logging and you can analize your instance using various system log files. -In addition to system log files, GitLab Enterprise Edition comes with Audit Events. Find more about them [in Audit Events documentation](http://doc.gitlab.com/ee/administration/audit_events.html) - -System log files are typically plain text in a standard log file format. This guide talks about how to read and use these system log files. - -#### production.log -This file lives in `/var/log/gitlab/gitlab-rails/production.log` for omnibus package or in `/home/git/gitlab/logs/production.log` for installations from the source. - -This file contains information about all performed requests. You can see url and type of request, IP address and what exactly parts of code were involved to service this particular request. Also you can see all SQL request that have been performed and how much time it took. -This task is more useful for GitLab contributors and developers. Use part of this log file when you are going to report bug. - -``` -Started GET "/gitlabhq/yaml_db/tree/master" for 168.111.56.1 at 2015-02-12 19:34:53 +0200 -Processing by Projects::TreeController#show as HTML - Parameters: {"project_id"=>"gitlabhq/yaml_db", "id"=>"master"} - - ... [CUT OUT] - - amespaces"."created_at" DESC, "namespaces"."id" DESC LIMIT 1 [["id", 26]] - CACHE (0.0ms) SELECT "members".* FROM "members" WHERE "members"."source_type" = 'Project' AND "members"."type" IN ('ProjectMember') AND "members"."source_id" = $1 AND "members"."source_type" = $2 AND "members"."user_id" = 1 ORDER BY "members"."created_at" DESC, "members"."id" DESC LIMIT 1 [["source_id", 18], ["source_type", "Project"]] - CACHE (0.0ms) SELECT "members".* FROM "members" WHERE "members"."source_type" = 'Project' AND "members". -  (1.4ms) SELECT COUNT(*) FROM "merge_requests" WHERE "merge_requests"."target_project_id" = $1 AND ("merge_requests"."state" IN ('opened','reopened')) [["target_project_id", 18]] - Rendered layouts/nav/_project.html.haml (28.0ms) - Rendered layouts/_collapse_button.html.haml (0.2ms) - Rendered layouts/_flash.html.haml (0.1ms) - Rendered layouts/_page.html.haml (32.9ms) -Completed 200 OK in 166ms (Views: 117.4ms | ActiveRecord: 27.2ms) -``` -In this example we can see that server processed HTTP request with url `/gitlabhq/yaml_db/tree/master` from IP 168.111.56.1 at 2015-02-12 19:34:53 +0200. Also we can see that request was processed by Projects::TreeController. - -#### application.log -This file lives in `/var/log/gitlab/gitlab-rails/application.log` for omnibus package or in `/home/git/gitlab/logs/application.log` for installations from the source. - -This log file helps you discover events happening in your instance such as user creation, project removing and so on. - -``` -October 06, 2014 11:56: User "Administrator" (admin@example.com) was created -October 06, 2014 11:56: Documentcloud created a new project "Documentcloud / Underscore" -October 06, 2014 11:56: Gitlab Org created a new project "Gitlab Org / Gitlab Ce" -October 07, 2014 11:25: User "Claudie Hodkiewicz" (nasir_stehr@olson.co.uk) was removed -October 07, 2014 11:25: Project "project133" was removed -``` -#### githost.log -This file lives in `/var/log/gitlab/gitlab-rails/githost.log` for omnibus package or in `/home/git/gitlab/logs/githost.log` for installations from the source. - -The GitLab has to interact with git repositories but in some rare cases something can go wrong and in this case you will know what exactly happened. This log file contains all failed requests from GitLab to git repository. In majority of cases this file will be useful for developers only. -``` -December 03, 2014 13:20 -> ERROR -> Command failed [1]: /usr/bin/git --git-dir=/Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/gitlab-satellites/group184/gitlabhq/.git --work-tree=/Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/gitlab-satellites/group184/gitlabhq merge --no-ff -mMerge branch 'feature_conflict' into 'feature' source/feature_conflict - -error: failed to push some refs to '/Users/vsizov/gitlab-development-kit/repositories/gitlabhq/gitlab_git.git' -``` - -#### satellites.log -This file lives in `/var/log/gitlab/gitlab-rails/satellites.log` for omnibus package or in `/home/git/gitlab/logs/satellites.log` for installations from the source. - -In some cases GitLab should perform write actions to git repository, for example when it is needed to merge the merge request or edit a file with online editor. If something went wrong you can look into this file to find out what exactly happened. -``` -October 07, 2014 11:36: Failed to create satellite for Chesley Weimann III / project1817 -October 07, 2014 11:36: PID: 1872: git clone /Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/repositories/conrad6841/gitlabhq.git /Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/gitlab-satellites/conrad6841/gitlabhq -October 07, 2014 11:36: PID: 1872: -> fatal: repository '/Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/repositories/conrad6841/gitlabhq.git' does not exist -``` - -#### sidekiq.log -This file lives in `/var/log/gitlab/gitlab-rails/sidekiq.log` for omnibus package or in `/home/git/gitlab/logs/sidekiq.log` for installations from the source. - -GitLab uses background jobs for processing tasks which can take a long time. All information about processing these jobs are writing down to this file. -``` -2014-06-10T07:55:20Z 2037 TID-tm504 ERROR: /opt/bitnami/apps/discourse/htdocs/vendor/bundle/ruby/1.9.1/gems/redis-3.0.7/lib/redis/client.rb:228:in `read' -2014-06-10T18:18:26Z 14299 TID-55uqo INFO: Booting Sidekiq 3.0.0 with redis options {:url=>"redis://localhost:6379/0", :namespace=>"sidekiq"} -``` - -#### gitlab-shell.log -This file lives in `/var/log/gitlab/gitlab-shell/gitlab-shell.log` for omnibus package or in `/home/git/gitlab-shell/logs/sidekiq.log` for installations from the source. - -gitlab-shell is using by Gitlab for executing git commands and provide ssh access to git repositories. - -``` -I, [2015-02-13T06:17:00.671315 #9291] INFO -- : Adding project root/example.git at . -I, [2015-02-13T06:17:00.679433 #9291] INFO -- : Moving existing hooks directory and simlinking global hooks directory for /var/opt/gitlab/git-data/repositories/root/example.git. -``` - -#### unicorn_stderr.log -This file lives in `/var/log/gitlab/unicorn/unicorn_stderr.log` for omnibus package or in `/home/git/gitlab/logs/unicorn_stderr.log` for installations from the source. - -Unicorn is a high-performance forking Web server which is used for serving GitLab application. You can look at this log, for example, if your application does not respond. This log cantains all information about state of unicorn processes at any given time. - -``` -I, [2015-02-13T06:14:46.680381 #9047] INFO -- : Refreshing Gem list -I, [2015-02-13T06:14:56.931002 #9047] INFO -- : listening on addr=127.0.0.1:8080 fd=12 -I, [2015-02-13T06:14:56.931381 #9047] INFO -- : listening on addr=/var/opt/gitlab/gitlab-rails/sockets/gitlab.socket fd=13 -I, [2015-02-13T06:14:56.936638 #9047] INFO -- : master process ready -I, [2015-02-13T06:14:56.946504 #9092] INFO -- : worker=0 spawned pid=9092 -I, [2015-02-13T06:14:56.946943 #9092] INFO -- : worker=0 ready -I, [2015-02-13T06:14:56.947892 #9094] INFO -- : worker=1 spawned pid=9094 -I, [2015-02-13T06:14:56.948181 #9094] INFO -- : worker=1 ready -W, [2015-02-13T07:16:01.312916 #9094] WARN -- : #: worker (pid: 9094) exceeds memory limit (320626688 bytes > 247066940 bytes) -W, [2015-02-13T07:16:01.313000 #9094] WARN -- : Unicorn::WorkerKiller send SIGQUIT (pid: 9094) alive: 3621 sec (trial 1) -I, [2015-02-13T07:16:01.530733 #9047] INFO -- : reaped # worker=1 -I, [2015-02-13T07:16:01.534501 #13379] INFO -- : worker=1 spawned pid=13379 -I, [2015-02-13T07:16:01.534848 #13379] INFO -- : worker=1 ready -``` diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md deleted file mode 100644 index 1d5fd4c8b0dc0f3fcb1919124903530e0a6517de..0000000000000000000000000000000000000000 --- a/doc/markdown/markdown.md +++ /dev/null @@ -1,532 +0,0 @@ -# Markdown - -## Table of Contents - -**[GitLab Flavored Markdown](#gitlab-flavored-markdown-gfm)** - -* [Newlines](#newlines) -* [Multiple underscores in words](#multiple-underscores-in-words) -* [URL auto-linking](#url-auto-linking) -* [Code and Syntax Highlighting](#code-and-syntax-highlighting) -* [Emoji](#emoji) -* [Special GitLab references](#special-gitlab-references) -* [Task lists](#task-lists) - -**[Standard Markdown](#standard-markdown)** - -* [Headers](#headers) -* [Emphasis](#emphasis) -* [Lists](#lists) -* [Links](#links) -* [Images](#images) -* [Blockquotes](#blockquotes) -* [Inline HTML](#inline-html) -* [Horizontal Rule](#horizontal-rule) -* [Line Breaks](#line-breaks) -* [Tables](#tables) - -**[References](#references)** - -## GitLab Flavored Markdown (GFM) - -For GitLab we developed something we call "GitLab Flavored Markdown" (GFM). It extends the standard Markdown in a few significant ways to add some useful functionality. - -You can use GFM in - -- commit messages -- comments -- issues -- merge requests -- milestones -- wiki pages - -You can also use other rich text files in GitLab. You might have to install a dependency to do so. Please see the [github-markup gem readme](https://github.com/gitlabhq/markup#markups) for more information. - -## Newlines - -GFM honors the markdown specification in how [paragraphs and line breaks are handled](http://daringfireball.net/projects/markdown/syntax#p). - -A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. -Line-breaks, or softreturns, are rendered if you end a line with two or more spaces - - Roses are red [followed by two or more spaces] - Violets are blue - - Sugar is sweet - -Roses are red -Violets are blue - -Sugar is sweet - -## Multiple underscores in words - -It is not reasonable to italicize just _part_ of a word, especially when you're dealing with code and names that often appear with multiple underscores. Therefore, GFM ignores multiple underscores in words. - - perform_complicated_task - do_this_and_do_that_and_another_thing - -perform_complicated_task -do_this_and_do_that_and_another_thing - -## URL auto-linking - -GFM will autolink standard URLs you copy and paste into your text. So if you want to link to a URL (instead of a textural link), you can simply put the URL in verbatim and it will be turned into a link to that URL. - - http://www.google.com - -http://www.google.com - -## Code and Syntax Highlighting - -Blocks of code are either fenced by lines with three back-ticks ```, or are indented with four spaces. Only the fenced code blocks support syntax highlighting. - -```no-highlight -Inline `code` has `back-ticks around` it. -``` - -Inline `code` has `back-ticks around` it. - -Example: - - ```javascript - var s = "JavaScript syntax highlighting"; - alert(s); - ``` - - ```python - def function(): - #indenting works just fine in the fenced code block - s = "Python syntax highlighting" - print s - ``` - - ```ruby - require 'redcarpet' - markdown = Redcarpet.new("Hello World!") - puts markdown.to_html - ``` - - ``` - No language indicated, so no syntax highlighting. - s = "There is no highlighting for this." - But let's throw in a tag. - ``` - -becomes: - -```javascript -var s = "JavaScript syntax highlighting"; -alert(s); -``` - -```python -def function(): - #indenting works just fine in the fenced code block - s = "Python syntax highlighting" - print s -``` - -```ruby -require 'redcarpet' -markdown = Redcarpet.new("Hello World!") -puts markdown.to_html -``` - -``` -No language indicated, so no syntax highlighting. -s = "There is no highlighting for this." -But let's throw in a tag. -``` - -## Emoji - - Sometimes you want to :monkey: around a bit and add some :star2: to your :speech_balloon:. Well we have a gift for you: - - :zap: You can use emoji anywhere GFM is supported. :v: - - You can use it to point out a :bug: or warn about :speak_no_evil: patches. And if someone improves your really :snail: code, send them some :birthday:. People will :heart: you for that. - - If you are new to this, don't be :fearful:. You can easily join the emoji :family:. All you need to do is to look up on the supported codes. - - Consult the [Emoji Cheat Sheet](http://emoji.codes) for a list of all supported emoji codes. :thumbsup: - -Sometimes you want to :monkey: around a bit and add some :star2: to your :speech_balloon:. Well we have a gift for you: - -:zap: You can use emoji anywhere GFM is supported. :v: - -You can use it to point out a :bug: or warn about :speak_no_evil: patches. And if someone improves your really :snail: code, send them some :birthday:. People will :heart: you for that. - -If you are new to this, don't be :fearful:. You can easily join the emoji :family:. All you need to do is to look up on the supported codes. - -Consult the [Emoji Cheat Sheet](http://emoji.codes) for a list of all supported emoji codes. :thumbsup: - -## Special GitLab References - -GFM recognized special references. - -You can easily reference e.g. an issue, a commit, a team member or even the whole team within a project. - -GFM will turn that reference into a link so you can navigate between them easily. - -GFM will recognize the following: - -- @foo : for specific team members or groups -- @all : for the whole team -- #123 : for issues -- !123 : for merge requests -- $123 : for snippets -- 1234567 : for commits -- \[file\](path/to/file) : for file references - -GFM also recognizes references to commits, issues, and merge requests in other projects: - -- namespace/project#123 : for issues -- namespace/project!123 : for merge requests -- namespace/project@1234567 : for commits - -## Task Lists - -You can add task lists to merge request and issue descriptions to keep track of to-do items. To create a task, add an unordered list to the description in an issue or merge request, formatted like so: - -```no-highlight -* [x] Completed task -* [ ] Unfinished task - * [x] Nested task -``` - -Task lists can only be created in descriptions, not in titles or comments. Task item state can be managed by editing the description's Markdown or by clicking the rendered checkboxes. - -# Standard Markdown - -## Headers - -```no-highlight -# H1 -## H2 -### H3 -#### H4 -##### H5 -###### H6 - -Alternatively, for H1 and H2, an underline-ish style: - -Alt-H1 -====== - -Alt-H2 ------- -``` - -# H1 -## H2 -### H3 -#### H4 -##### H5 -###### H6 - -Alternatively, for H1 and H2, an underline-ish style: - -Alt-H1 -====== - -Alt-H2 ------- - -### Header IDs and links - -All markdown rendered headers automatically get IDs, except for comments. - -On hover a link to those IDs becomes visible to make it easier to copy the link to the header to give it to someone else. - -The IDs are generated from the content of the header according to the following rules: - -1. remove the heading hashes `#` and process the rest of the line as it would be processed if it were not a header -2. from the result, remove all HTML tags, but keep their inner content -3. convert all characters to lowercase -4. convert all characters except `[a-z0-9_-]` into hyphens `-` -5. transform multiple adjacent hyphens into a single hyphen -6. remove trailing and heading hyphens - -For example: - -``` -###### ..Ab_c-d. e [anchor](URL) ![alt text](URL).. -``` - -which renders as: - -###### ..Ab_c-d. e [anchor](URL) ![alt text](URL).. - -will first be converted by step 1) into a string like: - -``` -..Ab_c-d. e <a href="URL">anchor</a> <img src="URL" alt="alt text"/>.. -``` - -After removing the tags in step 2) we get: - -``` -..Ab_c-d. e anchor .. -``` - -And applying all the other steps gives the id: - -``` -ab_c-d-e-anchor -``` - -Note in particular how: - -- for markdown anchors `[text](URL)`, only the `text` is used -- markdown images `![alt](URL)` are completely ignored - -## Emphasis - -```no-highlight -Emphasis, aka italics, with *asterisks* or _underscores_. - -Strong emphasis, aka bold, with **asterisks** or __underscores__. - -Combined emphasis with **asterisks and _underscores_**. - -Strikethrough uses two tildes. ~~Scratch this.~~ -``` - -Emphasis, aka italics, with *asterisks* or _underscores_. - -Strong emphasis, aka bold, with **asterisks** or __underscores__. - -Combined emphasis with **asterisks and _underscores_**. - -Strikethrough uses two tildes. ~~Scratch this.~~ - -## Lists - -```no-highlight -1. First ordered list item -2. Another item - * Unordered sub-list. -1. Actual numbers don't matter, just that it's a number - 1. Ordered sub-list -4. And another item. - - Some text that should be aligned with the above item. - -* Unordered list can use asterisks -- Or minuses -+ Or pluses -``` - -1. First ordered list item -2. Another item - * Unordered sub-list. -1. Actual numbers don't matter, just that it's a number - 1. Ordered sub-list -4. And another item. - - Some text that should be aligned with the above item. - -* Unordered list can use asterisks -- Or minuses -+ Or pluses - -## Links - -There are two ways to create links, inline-style and reference-style. - - [I'm an inline-style link](https://www.google.com) - - [I'm a reference-style link][Arbitrary case-insensitive reference text] - - [I'm a relative reference to a repository file](LICENSE) - - [You can use numbers for reference-style link definitions][1] - - Or leave it empty and use the [link text itself][] - - Some text to show that the reference links can follow later. - - [arbitrary case-insensitive reference text]: https://www.mozilla.org - [1]: http://slashdot.org - [link text itself]: http://www.reddit.com - -[I'm an inline-style link](https://www.google.com) - -[I'm a reference-style link][Arbitrary case-insensitive reference text] - -[I'm a relative reference to a repository file](LICENSE) - -[You can use numbers for reference-style link definitions][1] - -Or leave it empty and use the [link text itself][] - -Some text to show that the reference links can follow later. - -[arbitrary case-insensitive reference text]: https://www.mozilla.org -[1]: http://slashdot.org -[link text itself]: http://www.reddit.com - -**Note** - -Relative links do not allow referencing project files in a wiki page or wiki page in a project file. The reason for this is that, in GitLab, wiki is always a separate git repository. For example: - -`[I'm a reference-style link][style]` - -will point the link to `wikis/style` when the link is inside of a wiki markdown file. - -## Images - - Here's our logo (hover to see the title text): - - Inline-style: - ![alt text](assets/logo-white.png) - - Reference-style: - ![alt text1][logo] - - [logo]: assets/logo-white.png - -Here's our logo: - -Inline-style: - -![alt text](/assets/logo-white.png) - -Reference-style: - -![alt text][logo] - -[logo]: /assets/logo-white.png - -## Blockquotes - -```no-highlight -> Blockquotes are very handy in email to emulate reply text. -> This line is part of the same quote. - -Quote break. - -> This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can *put* **Markdown** into a blockquote. -``` - -> Blockquotes are very handy in email to emulate reply text. -> This line is part of the same quote. - -Quote break. - -> This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can *put* **Markdown** into a blockquote. - -## Inline HTML - -You can also use raw HTML in your Markdown, and it'll mostly work pretty well. - -See the documentation for HTML::Pipeline's [SanitizationFilter](http://www.rubydoc.info/gems/html-pipeline/HTML/Pipeline/SanitizationFilter#WHITELIST-constant) class for the list of allowed HTML tags and attributes. In addition to the default `SanitizationFilter` whitelist, GitLab allows the `class`, `id`, and `style` attributes. - -```no-highlight -
    -
    Definition list
    -
    Is something people use sometimes.
    - -
    Markdown in HTML
    -
    Does *not* work **very** well. Use HTML tags.
    -
    -``` - -
    -
    Definition list
    -
    Is something people use sometimes.
    - -
    Markdown in HTML
    -
    Does *not* work **very** well. Use HTML tags.
    -
    - -## Horizontal Rule - -``` -Three or more... - ---- - -Hyphens - -*** - -Asterisks - -___ - -Underscores -``` - -Three or more... - ---- - -Hyphens - -*** - -Asterisks - -___ - -Underscores - -## Line Breaks - -My basic recommendation for learning how line breaks work is to experiment and discover -- hit <Enter> once (i.e., insert one newline), then hit it twice (i.e., insert two newlines), see what happens. You'll soon learn to get what you want. "Markdown Toggle" is your friend. - -Here are some things to try out: - -``` -Here's a line for us to start with. - -This line is separated from the one above by two newlines, so it will be a *separate paragraph*. - -This line is also a separate paragraph, but... -This line is only separated by a single newline, so it's a separate line in the *same paragraph*. - -This line is also a separate paragraph, and... -This line is on its own line, because the previous line ends with two -spaces. -``` - -Here's a line for us to start with. - -This line is separated from the one above by two newlines, so it will be a *separate paragraph*. - -This line is also begins a separate paragraph, but... -This line is only separated by a single newline, so it's a separate line in the *same paragraph*. - -This line is also a separate paragraph, and... -This line is on its own line, because the previous line ends with two -spaces. - -## Tables - -Tables aren't part of the core Markdown spec, but they are part of GFM and Markdown Here supports them. - -``` -| header 1 | header 2 | -| -------- | -------- | -| cell 1 | cell 2 | -| cell 3 | cell 4 | -``` - -Code above produces next output: - -| header 1 | header 2 | -| -------- | -------- | -| cell 1 | cell 2 | -| cell 3 | cell 4 | - -**Note** - -The row of dashes between the table header and body must have at least three dashes in each column. - -## References - -- This document leveraged heavily from the [Markdown-Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). -- The [Markdown Syntax Guide](http://daringfireball.net/projects/markdown/syntax) at Daring Fireball is an excellent resource for a detailed explanation of standard markdown. -- [Dillinger.io](http://dillinger.io) is a handy tool for testing standard markdown. diff --git a/doc/operations/README.md b/doc/operations/README.md deleted file mode 100644 index f1456c6c8e2abae2faf7076078e8157a96b71765..0000000000000000000000000000000000000000 --- a/doc/operations/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# GitLab operations - -- [Sidekiq MemoryKiller](sidekiq_memory_killer.md) -- [Cleaning up Redis sessions](cleaning_up_redis_sessions.md) diff --git a/doc/operations/cleaning_up_redis_sessions.md b/doc/operations/cleaning_up_redis_sessions.md deleted file mode 100644 index 93521e976d51e05204c34addbedc8cb0e4c514ab..0000000000000000000000000000000000000000 --- a/doc/operations/cleaning_up_redis_sessions.md +++ /dev/null @@ -1,52 +0,0 @@ -# Cleaning up stale Redis sessions - -Since version 6.2, GitLab stores web user sessions as key-value pairs in Redis. -Prior to GitLab 7.3, user sessions did not automatically expire from Redis. If -you have been running a large GitLab server (thousands of users) since before -GitLab 7.3 we recommend cleaning up stale sessions to compact the Redis -database after you upgrade to GitLab 7.3. You can also perform a cleanup while -still running GitLab 7.2 or older, but in that case new stale sessions will -start building up again after you clean up. - -In GitLab versions prior to 7.3.0, the session keys in Redis are 16-byte -hexadecimal values such as '976aa289e2189b17d7ef525a6702ace9'. Starting with -GitLab 7.3.0, the keys are -prefixed with 'session:gitlab:', so they would look like -'session:gitlab:976aa289e2189b17d7ef525a6702ace9'. Below we describe how to -remove the keys in the old format. - -First we define a shell function with the proper Redis connection details. - -``` -rcli() { - # This example works for Omnibus installations of GitLab 7.3 or newer. For an - # installation from source you will have to change the socket path and the - # path to redis-cli. - sudo /opt/gitlab/embedded/bin/redis-cli -s /var/opt/gitlab/redis/redis.socket "$@" -} - -# test the new shell function; the response should be PONG -rcli ping -``` - -Now we do a search to see if there are any session keys in the old format for -us to clean up. - -``` -# returns the number of old-format session keys in Redis -rcli keys '*' | grep '^[a-f0-9]\{32\}$' | wc -l -``` - -If the number is larger than zero, you can proceed to expire the keys from -Redis. If the number is zero there is nothing to clean up. - -``` -# Tell Redis to expire each matched key after 600 seconds. -rcli keys '*' | grep '^[a-f0-9]\{32\}$' | awk '{ print "expire", $0, 600 }' | rcli -# This will print '(integer) 1' for each key that gets expired. -``` - -Over the next 15 minutes (10 minutes expiry time plus 5 minutes Redis -background save interval) your Redis database will be compacted. If you are -still using GitLab 7.2, users who are not clicking around in GitLab during the -10 minute expiry window will be signed out of GitLab. diff --git a/doc/operations/sidekiq_memory_killer.md b/doc/operations/sidekiq_memory_killer.md deleted file mode 100644 index 867b01b0d5ae746e2e3e459296ace116a9795f95..0000000000000000000000000000000000000000 --- a/doc/operations/sidekiq_memory_killer.md +++ /dev/null @@ -1,38 +0,0 @@ -# Sidekiq MemoryKiller - -The GitLab Rails application code suffers from memory leaks. For web requests -this problem is made manageable using -[unicorn-worker-killer](https://github.com/kzk/unicorn-worker-killer) which -restarts Unicorn worker processes in between requests when needed. The Sidekiq -MemoryKiller applies the same approach to the Sidekiq processes used by GitLab -to process background jobs. - -Unlike unicorn-worker-killer, which is enabled by default for all GitLab -installations since GitLab 6.4, the Sidekiq MemoryKiller is enabled by default -_only_ for Omnibus packages. The reason for this is that the MemoryKiller -relies on Runit to restart Sidekiq after a memory-induced shutdown and GitLab -installations from source do not all use Runit or an equivalent. - -With the default settings, the MemoryKiller will cause a Sidekiq restart no -more often than once every 15 minutes, with the restart causing about one -minute of delay for incoming background jobs. - -## Configuring the MemoryKiller - -The MemoryKiller is controlled using environment variables. - -- `SIDEKIQ_MEMORY_KILLER_MAX_RSS`: if this variable is set, and its value is - greater than 0, then after each Sidekiq job, the MemoryKiller will check the - RSS of the Sidekiq process that executed the job. If the RSS of the Sidekiq - process (expressed in kilobytes) exceeds SIDEKIQ_MEMORY_KILLER_MAX_RSS, a - delayed shutdown is triggered. The default value for Omnibus packages is set - [in the omnibus-gitlab - repository](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-cookbooks/gitlab/attributes/default.rb). -- `SIDEKIQ_MEMORY_KILLER_GRACE_TIME`: defaults 900 seconds (15 minutes). When - a shutdown is triggered, the Sidekiq process will keep working normally for - another 15 minutes. -- `SIDEKIQ_MEMORY_KILLER_SHUTDOWN_WAIT`: defaults to 30 seconds. When the grace - time has expired, the MemoryKiller tells Sidekiq to stop accepting new jobs. - Existing jobs get 30 seconds to finish. After that, the MemoryKiller tells - Sidekiq to shut down, and an external supervision mechanism (e.g. Runit) must - restart Sidekiq. diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md deleted file mode 100644 index 8cfa7f9c876f35bd3c739dc9d518a2ad05ae42b1..0000000000000000000000000000000000000000 --- a/doc/permissions/permissions.md +++ /dev/null @@ -1,55 +0,0 @@ -# Permissions - -Users have different abilities depending on the access level they have in a particular group or project. - -If a user is both in a project group and in the project itself, the highest permission level is used. - -If a user is a GitLab administrator they receive all permissions. - -## Project - -| Action | Guest | Reporter | Developer | Master | Owner | -|---------------------------------------|---------|------------|-------------|----------|--------| -| Create new issue | ✓ | ✓ | ✓ | ✓ | ✓ | -| Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ | -| Pull project code | | ✓ | ✓ | ✓ | ✓ | -| Download project | | ✓ | ✓ | ✓ | ✓ | -| Create code snippets | | ✓ | ✓ | ✓ | ✓ | -| Create new merge request | | | ✓ | ✓ | ✓ | -| Create new branches | | | ✓ | ✓ | ✓ | -| Push to non-protected branches | | | ✓ | ✓ | ✓ | -| Force push to non-protected branches | | | ✓ | ✓ | ✓ | -| Remove non-protected branches | | | ✓ | ✓ | ✓ | -| Add tags | | | ✓ | ✓ | ✓ | -| Write a wiki | | | ✓ | ✓ | ✓ | -| Manage issue tracker | | | ✓ | ✓ | ✓ | -| Manage labels | | | ✓ | ✓ | ✓ | -| Create new milestones | | | | ✓ | ✓ | -| Add new team members | | | | ✓ | ✓ | -| Push to protected branches | | | | ✓ | ✓ | -| Enable/disable branch protection | | | | ✓ | ✓ | -| Turn on/off prot. branch push for devs| | | | ✓ | ✓ | -| Rewrite/remove git tags | | | | ✓ | ✓ | -| Edit project | | | | ✓ | ✓ | -| Add deploy keys to project | | | | ✓ | ✓ | -| Configure project hooks | | | | ✓ | ✓ | -| Switch visibility level | | | | | ✓ | -| Transfer project to another namespace | | | | | ✓ | -| Remove project | | | | | ✓ | -| Force push to protected branches | | | | | | -| Remove protected branches | | | | | | - -## Group - -In order for a group to appear as public and be browsable, it must contain at -least one public project. - -Any user can remove themselves from a group, unless they are the last Owner of the group. - -| Action | Guest | Reporter | Developer | Master | Owner | -|-------------------------|-------|----------|-----------|--------|-------| -| Browse group | ✓ | ✓ | ✓ | ✓ | ✓ | -| Edit group | | | | | ✓ | -| Create project in group | | | | ✓ | ✓ | -| Manage group members | | | | | ✓ | -| Remove group | | | | | ✓ | diff --git a/doc/project_services/bamboo.md b/doc/project_services/bamboo.md deleted file mode 100644 index 51668128c6245cf8222875a15cc2bb8084460ded..0000000000000000000000000000000000000000 --- a/doc/project_services/bamboo.md +++ /dev/null @@ -1,60 +0,0 @@ -# Atlassian Bamboo CI Service - -GitLab provides integration with Atlassian Bamboo for continuous integration. -When configured, pushes to a project will trigger a build in Bamboo automatically. -Merge requests will also display CI status showing whether the build is pending, -failed, or completed successfully. It also provides a link to the Bamboo build -page for more information. - -Bamboo doesn't quite provide the same features as a traditional build system when -it comes to accepting webhooks and commit data. There are a few things that -need to be configured in a Bamboo build plan before GitLab can integrate. - -## Setup - -### Complete these steps in Bamboo: - -1. Navigate to a Bamboo build plan and choose 'Configure plan' from the 'Actions' -dropdown. -1. Select the 'Triggers' tab. -1. Click 'Add trigger'. -1. Enter a description such as 'GitLab trigger' -1. Choose 'Repository triggers the build when changes are committed' -1. Check one or more repositories checkboxes -1. Enter the GitLab IP address in the 'Trigger IP addresses' box. This is a -whitelist of IP addresses that are allowed to trigger Bamboo builds. -1. Save the trigger. -1. In the left pane, select a build stage. If you have multiple build stages -you want to select the last stage that contains the git checkout task. -1. Select the 'Miscellaneous' tab. -1. Under 'Pattern Match Labelling' put '${bamboo.repository.revision.number}' -in the 'Labels' box. -1. Save - -Bamboo is now ready to accept triggers from GitLab. Next, set up the Bamboo -service in GitLab - -### Complete these steps in GitLab: - -1. Navigate to the project you want to configure to trigger builds. -1. Select 'Settings' in the top navigation. -1. Select 'Services' in the left navigation. -1. Click 'Atlassian Bamboo CI' -1. Select the 'Active' checkbox. -1. Enter the base URL of your Bamboo server. 'https://bamboo.example.com' -1. Enter the build key from your Bamboo build plan. Build keys are a short, -all capital letter, identifier that is unique. It will be something like PR-BLD -1. If necessary, enter username and password for a Bamboo user that has -access to trigger the build plan. Leave these fields blank if you do not require -authentication. -1. Save or optionally click 'Test Settings'. Please note that 'Test Settings' -will actually trigger a build in Bamboo. - -## Troubleshooting - -If builds are not triggered, these are a couple of things to keep in mind. - -1. Ensure you entered the right GitLab IP address in Bamboo under 'Trigger -IP addresses'. -1. Remember that GitLab only triggers builds on push events. A commit via the -web interface will not trigger CI currently. diff --git a/doc/project_services/hipchat.md b/doc/project_services/hipchat.md deleted file mode 100644 index 021a93a288ff9de25dac5cda9cca1cef36a93795..0000000000000000000000000000000000000000 --- a/doc/project_services/hipchat.md +++ /dev/null @@ -1,54 +0,0 @@ -# Atlassian HipChat - -GitLab provides a way to send HipChat notifications upon a number of events, -such as when a user pushes code, creates a branch or tag, adds a comment, and -creates a merge request. - -## Setup - -GitLab requires the use of a HipChat v2 API token to work. v1 tokens are -not supported at this time. Note the differences between v1 and v2 tokens: - -HipChat v1 API (legacy) supports "API Auth Tokens" in the Group API menu. A v1 -token is allowed to send messages to *any* room. - -HipChat v2 API has tokens that are can be created using the Integrations tab -in the Group or Room admin page. By design, these are lightweight tokens that -allow GitLab to send messages only to *one* room. - -### Complete these steps in HipChat: - -1. Go to: https://admin.hipchat.com/admin -1. Click on "Group Admin" -> "Integrations". -1. Find "Build Your Own!" and click "Create". -1. Select the desired room, name the integration "GitLab", and click "Create". -1. In the "Send messages to this room by posting this URL" column, you should -see a URL in the format: - -``` - https://api.hipchat.com/v2/room//notification?auth_token= -``` - -HipChat is now ready to accept messages from GitLab. Next, set up the HipChat -service in GitLab. - -### Complete these steps in GitLab: - -1. Navigate to the project you want to configure for notifications. -1. Select "Settings" in the top navigation. -1. Select "Services" in the left navigation. -1. Click "HipChat". -1. Select the "Active" checkbox. -1. Insert the `token` field from the URL into the `Token` field on the Web page. -1. Insert the `room` field from the URL into the `Room` field on the Web page. -1. Save or optionally click "Test Settings". - -## Troubleshooting - -If you do not see notifications, make sure you are using a HipChat v2 API -token, not a v1 token. - -Note that the v2 token is tied to a specific room. If you want to be able to -specify arbitrary rooms, you can create an API token for a specific user in -HipChat under "Account settings" and "API access". Use the `XXX` value under -`auth_token=XXX`. diff --git a/doc/project_services/irker.md b/doc/project_services/irker.md deleted file mode 100644 index 780a45bca20fbc5d533ec17f358f077337192f34..0000000000000000000000000000000000000000 --- a/doc/project_services/irker.md +++ /dev/null @@ -1,46 +0,0 @@ -# Irker IRC Gateway - -GitLab provides a way to push update messages to an Irker server. When -configured, pushes to a project will trigger the service to send data directly -to the Irker server. - -See the project homepage for further info: http://www.catb.org/esr/irker/ - -## Needed setup - -You will first need an Irker daemon. You can download the Irker code from its -gitorious repository on https://gitorious.org/irker: `git clone -git@gitorious.org:irker/irker.git`. Once you have downloaded the code, you can -run the python script named `irkerd`. This script is the gateway script, it acts -both as an IRC client, for sending messages to an IRC server obviously, and as a -TCP server, for receiving messages from the GitLab service. - -If the Irker server runs on the same machine, you are done. If not, you will -need to follow the firsts steps of the next section. - -## Optional setup - -In the `app/models/project_services/irker_service.rb` file, you can modify some -options in the `initialize_settings` method: -- **server_ip** (defaults to `localhost`): the server IP address where the -`irkerd` daemon runs; -- **server_port** (defaults to `6659`): the server port of the `irkerd` daemon; -- **max_channels** (defaults to `3`): the maximum number of recipients the -client is authorized to join, per project; -- **default_irc_uri** (no default) : if this option is set, it has to be in the -format `irc[s]://domain.name` and will be prepend to each and every channel -provided by the user which is not a full URI. - -If the Irker server and the GitLab application do not run on the same host, you -will **need** to setup at least the **server_ip** option. - -## Note on Irker recipients - -Irker accepts channel names of the form `chan` and `#chan`, both for the -`#chan` channel. If you want to send messages in query, you will need to add -`,isnick` avec the channel name, in this form: `Aorimn,isnick`. In this latter -case, `Aorimn` is treated as a nick and no more as a channel name. - -Irker can also join password-protected channels. Users need to append -`?key=thesecretpassword` to the chan name. - diff --git a/doc/project_services/project_services.md b/doc/project_services/project_services.md deleted file mode 100644 index 03937d20728f80821f63792fae2b1de8744cbd94..0000000000000000000000000000000000000000 --- a/doc/project_services/project_services.md +++ /dev/null @@ -1,20 +0,0 @@ -# Project Services - -__Project integrations with external services for continuous integration and more.__ - -## Services - -- Assembla -- [Atlassian Bamboo CI](bamboo.md) An Atlassian product for continuous integration. -- Build box -- Campfire -- Emails on push -- Flowdock -- Gemnasium -- GitLab CI -- [HipChat](hipchat.md) An Atlassian product for private group chat and instant messaging. -- [Irker](irker.md) An IRC gateway to receive messages on repository updates. -- Pivotal Tracker -- Pushover -- Slack -- TeamCity diff --git a/doc/public_access/public_access.md b/doc/public_access/public_access.md deleted file mode 100644 index bd439f7c6f356856be11fff0e92aa028ed183b13..0000000000000000000000000000000000000000 --- a/doc/public_access/public_access.md +++ /dev/null @@ -1,44 +0,0 @@ -# Public access - -GitLab allows you to open selected projects to be accessed **publicly** or **internally**. - -Projects with either of these visibility levels will be listed in the [public access directory](/public). - -Internal projects will only be available to authenticated users. - -## Public projects - -Public projects can be cloned **without any** authentication. - -It will also be listed on the [public access directory](/public). - -**Any logged in user** will have [Guest](../permissions/permissions) permissions on the repository. - -## Internal projects - -Internal projects can be cloned by any logged in user. - -It will also be listed on the [public access directory](/public) for logged in users. - -Any logged in user will have [Guest](../permissions/permissions) permissions on the repository. - -## How to change project visibility - -1. Go to your project dashboard -1. Click on the "Edit" tab -1. Change "Visibility Level" - -## Visibility of users - -The public page of users, located at `/u/username` is visible if either: - -- You are logged in. -- You are logged out, and the target user is authorized to (is Guest, Reporter, etc.) at least one public project. - -Otherwise, you will be redirected to the sign in page. - -When visiting the public page of an user, you will only see listed projects which you can view yourself. - -## Restricting the use of public or internal projects - -In the Admin area under Settings you can disable public projects or public and internal projects for the entire GitLab installation to prevent people making code public by accident. The restricted visibility settings do not apply to admin users. diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md deleted file mode 100644 index 770b7a70fe0a43e99badbfa0ad145d5c9813019c..0000000000000000000000000000000000000000 --- a/doc/raketasks/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Rake tasks - -- [Backup restore](backup_restore.md) -- [Cleanup](cleanup.md) -- [Features](features.md) -- [Maintenance](maintenance.md) and self-checks -- [User management](user_management.md) -- [Web hooks](web_hooks.md) -- [Import](import.md) of git repositories in bulk diff --git a/doc/raketasks/backup_hrz.png b/doc/raketasks/backup_hrz.png deleted file mode 100644 index 03e50df1d76e57a667770b062a82898a6fa34d6b..0000000000000000000000000000000000000000 Binary files a/doc/raketasks/backup_hrz.png and /dev/null differ diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md deleted file mode 100644 index 2e41fad89e78429fa79fddf2c80bc732d0e4426d..0000000000000000000000000000000000000000 --- a/doc/raketasks/backup_restore.md +++ /dev/null @@ -1,240 +0,0 @@ -# Backup restore - -![backup banner](backup_hrz.png) - -## Create a backup of the GitLab system - -A backup creates an archive file that contains the database, all repositories and all attachments. -This archive will be saved in backup_path (see `config/gitlab.yml`). -The filename will be `[TIMESTAMP]_gitlab_backup.tar`. This timestamp can be used to restore an specific backup. -You can only restore a backup to exactly the same version of GitLab that you created it on, for example 7.2.1. - -``` -# use this command if you've installed GitLab with the Omnibus package -sudo gitlab-rake gitlab:backup:create - -# if you've installed GitLab from source -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -Also you can choose what should be backed up by adding environment variable SKIP. Available options: db, -uploads (attachments), repositories. Use a comma to specify several options at the same time. - -``` -sudo gitlab-rake gitlab:backup:create SKIP=db,uploads -``` - -Example output: - -``` -Dumping database tables: -- Dumping table events... [DONE] -- Dumping table issues... [DONE] -- Dumping table keys... [DONE] -- Dumping table merge_requests... [DONE] -- Dumping table milestones... [DONE] -- Dumping table namespaces... [DONE] -- Dumping table notes... [DONE] -- Dumping table projects... [DONE] -- Dumping table protected_branches... [DONE] -- Dumping table schema_migrations... [DONE] -- Dumping table services... [DONE] -- Dumping table snippets... [DONE] -- Dumping table taggings... [DONE] -- Dumping table tags... [DONE] -- Dumping table users... [DONE] -- Dumping table users_projects... [DONE] -- Dumping table web_hooks... [DONE] -- Dumping table wikis... [DONE] -Dumping repositories: -- Dumping repository abcd... [DONE] -Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE] -Deleting tmp directories...[DONE] -Deleting old backups... [SKIPPING] -``` - -## Upload backups to remote (cloud) storage - -Starting with GitLab 7.4 you can let the backup script upload the '.tar' file it creates. -It uses the [Fog library](http://fog.io/) to perform the upload. -In the example below we use Amazon S3 for storage. -But Fog also lets you use [other storage providers](http://fog.io/storage/). - -For omnibus packages: - -```ruby -gitlab_rails['backup_upload_connection'] = { - 'provider' => 'AWS', - 'region' => 'eu-west-1', - 'aws_access_key_id' => 'AKIAKIAKI', - 'aws_secret_access_key' => 'secret123' -} -gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket' -``` - -For installations from source: - -```yaml - backup: - # snip - upload: - # Fog storage connection settings, see http://fog.io/storage/ . - connection: - provider: AWS - region: eu-west-1 - aws_access_key_id: AKIAKIAKI - aws_secret_access_key: 'secret123' - # The remote 'directory' to store your backups. For S3, this would be the bucket name. - remote_directory: 'my.s3.bucket' -``` - -If you are uploading your backups to S3 you will probably want to create a new -IAM user with restricted access rights. To give the upload user access only for -uploading backups create the following IAM profile, replacing `my.s3.bucket` -with the name of your bucket: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "Stmt1412062044000", - "Effect": "Allow", - "Action": [ - "s3:AbortMultipartUpload", - "s3:GetBucketAcl", - "s3:GetBucketLocation", - "s3:GetObject", - "s3:GetObjectAcl", - "s3:ListBucketMultipartUploads", - "s3:PutObject", - "s3:PutObjectAcl" - ], - "Resource": [ - "arn:aws:s3:::my.s3.bucket/*" - ] - }, - { - "Sid": "Stmt1412062097000", - "Effect": "Allow", - "Action": [ - "s3:GetBucketLocation", - "s3:ListAllMyBuckets" - ], - "Resource": [ - "*" - ] - }, - { - "Sid": "Stmt1412062128000", - "Effect": "Allow", - "Action": [ - "s3:ListBucket" - ], - "Resource": [ - "arn:aws:s3:::my.s3.bucket" - ] - } - ] -} -``` - -## Storing configuration files - -Please be informed that a backup does not store your configuration files. -If you use an Omnibus package please see the [instructions in the readme to backup your configuration](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#backup-and-restore-omnibus-gitlab-configuration). -If you have a cookbook installation there should be a copy of your configuration in Chef. -If you have an installation from source, please consider backing up your `gitlab.yml` file, any SSL keys and certificates, and your [SSH host keys](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079). - -## Restore a previously created backup - -You can only restore a backup to exactly the same version of GitLab that you created it on, for example 7.2.1. - -``` -# Omnibus package installation -sudo gitlab-rake gitlab:backup:restore - -# installation from source -bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` - -Options: - -``` -BACKUP=timestamp_of_backup (required if more than one backup exists) -``` - -Example output: - -``` -Unpacking backup... [DONE] -Restoring database tables: --- create_table("events", {:force=>true}) - -> 0.2231s -[...] -- Loading fixture events...[DONE] -- Loading fixture issues...[DONE] -- Loading fixture keys...[SKIPPING] -- Loading fixture merge_requests...[DONE] -- Loading fixture milestones...[DONE] -- Loading fixture namespaces...[DONE] -- Loading fixture notes...[DONE] -- Loading fixture projects...[DONE] -- Loading fixture protected_branches...[SKIPPING] -- Loading fixture schema_migrations...[DONE] -- Loading fixture services...[SKIPPING] -- Loading fixture snippets...[SKIPPING] -- Loading fixture taggings...[SKIPPING] -- Loading fixture tags...[SKIPPING] -- Loading fixture users...[DONE] -- Loading fixture users_projects...[DONE] -- Loading fixture web_hooks...[SKIPPING] -- Loading fixture wikis...[SKIPPING] -Restoring repositories: -- Restoring repository abcd... [DONE] -Deleting tmp directories...[DONE] -``` - -## Configure cron to make daily backups - -For Omnibus package installations, see https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#scheduling-a-backup . - -For installation from source: -``` -cd /home/git/gitlab -sudo -u git -H editor config/gitlab.yml # Enable keep_time in the backup section to automatically delete old backups -sudo -u git crontab -e # Edit the crontab for the git user -``` - -Add the following lines at the bottom: - -``` -# Create a full backup of the GitLab repositories and SQL database every day at 4am -0 4 * * * cd /home/git/gitlab && PATH=/usr/local/bin:/usr/bin:/bin bundle exec rake gitlab:backup:create RAILS_ENV=production CRON=1 -``` - -The `CRON=1` environment setting tells the backup script to suppress all progress output if there are no errors. -This is recommended to reduce cron spam. - -## Alternative backup strategies - -If your GitLab server contains a lot of Git repository data you may find the GitLab backup script to be too slow. -In this case you can consider using filesystem snapshots as part of your backup strategy. - -Example: Amazon EBS - -> A GitLab server using omnibus-gitlab hosted on Amazon AWS. -> An EBS drive containing an ext4 filesystem is mounted at `/var/opt/gitlab`. -> In this case you could make an application backup by taking an EBS snapshot. -> The backup includes all repositories, uploads and Postgres data. - -Example: LVM snapshots + rsync - -> A GitLab server using omnibus-gitlab, with an LVM logical volume mounted at `/var/opt/gitlab`. -> Replicating the `/var/opt/gitlab` directory using rsync would not be reliable because too many files would change while rsync is running. -> Instead of rsync-ing `/var/opt/gitlab`, we create a temporary LVM snapshot, which we mount as a read-only filesystem at `/mnt/gitlab_backup`. -> Now we can have a longer running rsync job which will create a consistent replica on the remote server. -> The replica includes all repositories, uploads and Postgres data. - -If you are running GitLab on a virtualized server you can possibly also create VM snapshots of the entire GitLab server. -It is not uncommon however for a VM snapshot to require you to power down the server, so this approach is probably of limited practical use. diff --git a/doc/raketasks/cleanup.md b/doc/raketasks/cleanup.md deleted file mode 100644 index 96d67f7b5d664fa24eaa378adc189849db2a9cf8..0000000000000000000000000000000000000000 --- a/doc/raketasks/cleanup.md +++ /dev/null @@ -1,23 +0,0 @@ -# Cleanup - -## Remove garbage from filesystem. Important! Data loss! - -Remove namespaces(dirs) from `/home/git/repositories` if they don't exist in GitLab database. - -``` -# omnibus-gitlab -sudo gitlab-rake gitlab:cleanup:dirs - -# installation from source -bundle exec rake gitlab:cleanup:dirs RAILS_ENV=production -``` - -Remove repositories (global only for now) from `/home/git/repositories` if they don't exist in GitLab database. - -``` -# omnibus-gitlab -sudo gitlab-rake gitlab:cleanup:repos - -# installation from source -bundle exec rake gitlab:cleanup:repos RAILS_ENV=production -``` diff --git a/doc/raketasks/features.md b/doc/raketasks/features.md deleted file mode 100644 index f9a46193547459a0117c525cd70587013bd2f066..0000000000000000000000000000000000000000 --- a/doc/raketasks/features.md +++ /dev/null @@ -1,20 +0,0 @@ -# Features - -## Enable usernames and namespaces for user projects - -This command will enable the namespaces feature introduced in v4.0. It will move every project in its namespace folder. - -Note: - -- Because the **repository location will change**, you will need to **update all your git URLs** to point to the new location. -- Username can be changed at [Profile / Account](/profile/account) - -**Example:** - -Old path: `git@example.org:myrepo.git` - -New path: `git@example.org:username/myrepo.git` or `git@example.org:groupname/myrepo.git` - -``` -bundle exec rake gitlab:enable_namespaces RAILS_ENV=production -``` diff --git a/doc/raketasks/import.md b/doc/raketasks/import.md deleted file mode 100644 index 8a38937062e003b658d54d081539f00029735543..0000000000000000000000000000000000000000 --- a/doc/raketasks/import.md +++ /dev/null @@ -1,68 +0,0 @@ -# Import bare repositories into your GitLab instance - -## Notes - -- The owner of the project will be the first admin -- The groups will be created as needed -- The owner of the group will be the first admin -- Existing projects will be skipped - -## How to use - -### Create a new folder inside the git repositories path. This will be the name of the new group. - -- For omnibus-gitlab, it is located at: `/var/opt/gitlab/git-data/repositories` by default, unless you changed -it in the `/etc/gitlab/gitlab.rb` file. -- For installations from source, it is usually located at: `/home/git/repositories` or you can see where -your repositories are located by looking at `config/gitlab.yml` under the `gitlab_shell => repos_path` entry. - -New folder needs to have git user ownership and read/write/execute access for git user and its group: - -``` -sudo -u git mkdir /var/opt/gitlab/git-data/repositories/new_group -``` - -If you are using an installation from source, replace `/var/opt/gitlab/git-data` -with `/home/git`. - -### Copy your bare repositories inside this newly created folder: - -``` -sudo cp -r /old/git/foo.git /var/opt/gitlab/git-data/repositories/new_group/ - -# Do this once when you are done copying git repositories -sudo chown -R git:git /var/opt/gitlab/git-data/repositories/new_group/ -``` - -`foo.git` needs to be owned by the git user and git users group. - -If you are using an installation from source, replace `/var/opt/gitlab/git-data` -with `/home/git`. - -### Run the command below depending on your type of installation: - -#### Omnibus Installation - -``` -$ sudo gitlab-rake gitlab:import:repos -``` - -#### Installation from source - -Before running this command you need to change the directory to where your GitLab installation is located: - -``` -$ cd /home/git/gitlab -$ sudo -u git -H bundle exec rake gitlab:import:repos RAILS_ENV=production -``` - -#### Example output - -``` -Processing abcd.git - * Created abcd (abcd.git) -Processing group/xyz.git - * Created Group group (2) - * Created xyz (group/xyz.git) -[...] -``` diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md deleted file mode 100644 index 41a994f3f68faba2016b34c6daa5628f0d2c7edf..0000000000000000000000000000000000000000 --- a/doc/raketasks/maintenance.md +++ /dev/null @@ -1,178 +0,0 @@ -# Maintenance - -## Gather information about GitLab and the system it runs on - -This command gathers information about your GitLab installation and the System it runs on. These may be useful when asking for help or reporting issues. - -``` -# omnibus-gitlab -sudo gitlab-rake gitlab:env:info - -# installation from source -bundle exec rake gitlab:env:info RAILS_ENV=production -``` - -Example output: - -``` -System information -System: Debian 7.8 -Current User: git -Using RVM: no -Ruby Version: 2.1.5p273 -Gem Version: 2.4.3 -Bundler Version: 1.7.6 -Rake Version: 10.3.2 -Sidekiq Version: 2.17.8 - -GitLab information -Version: 7.7.1 -Revision: 41ab9e1 -Directory: /home/git/gitlab -DB Adapter: postgresql -URL: https://gitlab.example.com -HTTP Clone URL: https://gitlab.example.com/some-project.git -SSH Clone URL: git@gitlab.example.com:some-project.git -Using LDAP: no -Using Omniauth: no - -GitLab Shell -Version: 2.4.1 -Repositories: /home/git/repositories/ -Hooks: /home/git/gitlab-shell/hooks/ -Git: /usr/bin/git -``` - -## Check GitLab configuration - -Runs the following rake tasks: - -- `gitlab:env:check` -- `gitlab:gitlab_shell:check` -- `gitlab:sidekiq:check` -- `gitlab:app:check` - -It will check that each component was setup according to the installation guide and suggest fixes for issues found. - -You may also have a look at our [Trouble Shooting Guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide). - -``` -# omnibus-gitlab -sudo gitlab-rake gitlab:check - -# installation from source -bundle exec rake gitlab:check RAILS_ENV=production -``` - -NOTE: Use SANITIZE=true for gitlab:check if you want to omit project names from the output. - -Example output: - -``` -Checking Environment ... - -Git configured for git user? ... yes -Has python2? ... yes -python2 is supported version? ... yes - -Checking Environment ... Finished - -Checking GitLab Shell ... - -GitLab Shell version? ... OK (1.2.0) -Repo base directory exists? ... yes -Repo base directory is a symlink? ... no -Repo base owned by git:git? ... yes -Repo base access is drwxrws---? ... yes -post-receive hook up-to-date? ... yes -post-receive hooks in repos are links: ... yes - -Checking GitLab Shell ... Finished - -Checking Sidekiq ... - -Running? ... yes - -Checking Sidekiq ... Finished - -Checking GitLab ... - -Database config exists? ... yes -Database is SQLite ... no -All migrations up? ... yes -GitLab config exists? ... yes -GitLab config outdated? ... no -Log directory writable? ... yes -Tmp directory writable? ... yes -Init script exists? ... yes -Init script up-to-date? ... yes -Projects have satellites? ... yes -Redis version >= 2.0.0? ... yes - -Checking GitLab ... Finished -``` - -## (Re-)Create satellite repositories - -This will create satellite repositories for all your projects. - -If necessary, remove the `repo_satellites` directory and rerun the commands below. - -``` -sudo -u git -H mkdir -p /home/git/gitlab-satellites -sudo -u git -H bundle exec rake gitlab:satellites:create RAILS_ENV=production -sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites -``` - -## Rebuild authorized_keys file - -In some case it is necessary to rebuild the `authorized_keys` file. - -For Omnibus-packages: -``` -sudo gitlab-rake gitlab:shell:setup -``` - -For installations from source: -``` -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:shell:setup RAILS_ENV=production -``` - -``` -This will rebuild an authorized_keys file. -You will lose any data stored in authorized_keys file. -Do you want to continue (yes/no)? yes -``` - -## Clear redis cache - -If for some reason the dashboard shows wrong information you might want to -clear Redis' cache. - -For Omnibus-packages: -``` -sudo gitlab-rake cache:clear -``` - -For installations from source: -``` -cd /home/git/gitlab -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production -``` - -## Precompile the assets - -Sometimes during version upgrades you might end up with some wrong CSS or -missing some icons. In that case, try to precompile the assets again. - -For Omnibus-packages: -``` -sudo gitlab-rake assets:precompile -``` - -For installations from source: -``` -cd /home/git/gitlab -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -``` diff --git a/doc/raketasks/user_management.md b/doc/raketasks/user_management.md deleted file mode 100644 index 80b01ca4043c03d66b27c39d01275b4926fe13d4..0000000000000000000000000000000000000000 --- a/doc/raketasks/user_management.md +++ /dev/null @@ -1,49 +0,0 @@ -# User management - -## Add user as a developer to all projects - -```bash -# omnibus-gitlab -sudo gitlab-rake gitlab:import:user_to_projects[username@domain.tld] - -# installation from source -bundle exec rake gitlab:import:user_to_projects[username@domain.tld] RAILS_ENV=production -``` - -## Add all users to all projects - -Notes: - -- admin users are added as masters - -```bash -# omnibus-gitlab -sudo gitlab-rake gitlab:import:all_users_to_all_projects - -# installation from source -bundle exec rake gitlab:import:all_users_to_all_projects RAILS_ENV=production -``` - -## Add user as a developer to all groups - -```bash -# omnibus-gitlab -sudo gitlab-rake gitlab:import:user_to_groups[username@domain.tld] - -# installation from source -bundle exec rake gitlab:import:user_to_groups[username@domain.tld] RAILS_ENV=production -``` - -## Add all users to all groups - -Notes: - -- admin users are added as owners so they can add additional users to the group - -```bash -# omnibus-gitlab -sudo gitlab-rake gitlab:import:all_users_to_all_groups - -# installation from source -bundle exec rake gitlab:import:all_users_to_all_groups RAILS_ENV=production -``` diff --git a/doc/raketasks/web_hooks.md b/doc/raketasks/web_hooks.md deleted file mode 100644 index 5a8b94af9b4bdd034bba760ec6ef53371f9e9c85..0000000000000000000000000000000000000000 --- a/doc/raketasks/web_hooks.md +++ /dev/null @@ -1,45 +0,0 @@ -# Web hooks - -## Add a web hook for **ALL** projects: - - # omnibus-gitlab - sudo gitlab-rake gitlab:web_hook:add URL="http://example.com/hook" - # source installations - bundle exec rake gitlab:web_hook:add URL="http://example.com/hook" RAILS_ENV=production - -## Add a web hook for projects in a given **NAMESPACE**: - - # omnibus-gitlab - sudo gitlab-rake gitlab:web_hook:add URL="http://example.com/hook" NAMESPACE=acme - # source installations - bundle exec rake gitlab:web_hook:add URL="http://example.com/hook" NAMESPACE=acme RAILS_ENV=production - -## Remove a web hook from **ALL** projects using: - - # omnibus-gitlab - sudo gitlab-rake gitlab:web_hook:rm URL="http://example.com/hook" - # source installations - bundle exec rake gitlab:web_hook:rm URL="http://example.com/hook" RAILS_ENV=production - -## Remove a web hook from projects in a given **NAMESPACE**: - - # omnibus-gitlab - sudo gitlab-rake gitlab:web_hook:rm URL="http://example.com/hook" NAMESPACE=acme - # source installations - bundle exec rake gitlab:web_hook:rm URL="http://example.com/hook" NAMESPACE=acme RAILS_ENV=production - -## List **ALL** web hooks: - - # omnibus-gitlab - sudo gitlab-rake gitlab:web_hook:list - # source installations - bundle exec rake gitlab:web_hook:list RAILS_ENV=production - -## List the web hooks from projects in a given **NAMESPACE**: - - # omnibus-gitlab - sudo gitlab-rake gitlab:web_hook:list NAMESPACE=/ - # source installations - bundle exec rake gitlab:web_hook:list NAMESPACE=/ RAILS_ENV=production - -> Note: `/` is the global namespace. diff --git a/doc/release/README.md b/doc/release/README.md deleted file mode 100644 index 1342b90f3b3c49888398bef85726fbb24cd31f57..0000000000000000000000000000000000000000 --- a/doc/release/README.md +++ /dev/null @@ -1,6 +0,0 @@ -GitLab has the following updates: - -- [Monthly release](monthly.md), every month on the 22nd. -- [Patch release](patch.md), if there are serious regressions. -- [Security](security.md), for security problems. -- [Master](master.md), update process for the master branch. diff --git a/doc/release/howto_rc1.md b/doc/release/howto_rc1.md deleted file mode 100644 index 07c703142d4d3dea5b5103f9e246f09a9080bfa5..0000000000000000000000000000000000000000 --- a/doc/release/howto_rc1.md +++ /dev/null @@ -1,55 +0,0 @@ -# How to create RC1 - -The RC1 release comes with the task to update the installation and upgrade docs. Be mindful that there might already be merge requests for this on GitLab or GitHub. - -### 1. Update the installation guide - -1. Check if it references the correct branch `x-x-stable` (doesn't exist yet, but that is okay) -1. Check the [GitLab Shell version](/lib/tasks/gitlab/check.rake#L782) -1. Check the [Git version](/lib/tasks/gitlab/check.rake#L794) -1. There might be other changes. Ask around. - -### 2. Create update guides - -[Follow this guide](howto_update_guides.md) to create update guides. - -### 3. Code quality indicators - -Make sure the code quality indicators are green / good. - -- [![Build status](http://ci.gitlab.org/projects/1/status.png?ref=master)](http://ci.gitlab.org/projects/1?ref=master) on ci.gitlab.org (master branch) - -- [![Build Status](https://semaphoreapp.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/243338/badge.png)](https://semaphoreapp.com/gitlabhq/gitlabhq) (master branch) - -- [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.png)](https://codeclimate.com/github/gitlabhq/gitlabhq) - -- [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq) this button can be yellow (small updates are available) but must not be red (a security fix or an important update is available) - -- [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq) - -### 4. Run release tool - -**Make sure EE `master` has latest changes from CE `master`** - -Get release tools - -``` -git clone git@dev.gitlab.org:gitlab/release-tools.git -cd release-tools -``` - -Release candidate creates stable branch from master. -So we need to sync master branch between all CE, EE and CI remotes. - -``` -bundle exec rake sync -``` - -Create release candidate and stable branch: - -``` -bundle exec rake release["x.x.0.rc1"] -``` - -Now developers can use master for merging new features. -So you should use stable branch for future code changes related to release. diff --git a/doc/release/howto_update_guides.md b/doc/release/howto_update_guides.md deleted file mode 100644 index 23d0959c33d590a4a15fa6ee2130184f7f88d176..0000000000000000000000000000000000000000 --- a/doc/release/howto_update_guides.md +++ /dev/null @@ -1,55 +0,0 @@ -# Create update guides - -1. Create: CE update guide from previous version. Like `7.3-to-7.4.md` -1. Create: CE to EE update guide in EE repository for latest version. -1. Update: `6.x-or-7.x-to-7.x.md` to latest version. -1. Create: CI update guide from previous version - -It's best to copy paste the previous guide and make changes where necessary. -The typical steps are listed below with any points you should specifically look at. - -#### 0. Any major changes? - -List any major changes here, so the user is aware of them before starting to upgrade. For instance: - -- Database updates -- Web server changes -- File structure changes - -#### 1. Stop server - -#### 2. Make backup - -#### 3. Do users need to update dependencies like `git`? - -- Check if the [GitLab Shell version](/lib/tasks/gitlab/check.rake#L782) changed since the last release. - -- Check if the [Git version](/lib/tasks/gitlab/check.rake#L794) changed since the last release. - -#### 4. Get latest code - -#### 5. Does GitLab shell need to be updated? - -#### 6. Install libs, migrations, etc. - -#### 7. Any config files updated since last release? - -Check if any of these changed since last release: - -- [lib/support/nginx/gitlab](/lib/support/nginx/gitlab) -- [lib/support/nginx/gitlab-ssl](/lib/support/nginx/gitlab-ssl) -- -- [config/gitlab.yml.example](/config/gitlab.yml.example) -- [config/unicorn.rb.example](/config/unicorn.rb.example) -- [config/database.yml.mysql](/config/database.yml.mysql) -- [config/database.yml.postgresql](/config/database.yml.postgresql) -- [config/initializers/rack_attack.rb.example](/config/initializers/rack_attack.rb.example) -- [config/resque.yml.example](/config/resque.yml.example) - -#### 8. Need to update init script? - -Check if the `init.d/gitlab` script changed since last release: [lib/support/init.d/gitlab](/lib/support/init.d/gitlab) - -#### 9. Start application - -#### 10. Check application status diff --git a/doc/release/master.md b/doc/release/master.md deleted file mode 100644 index 19070b46a0d8da91f4876206744307b4275a38c9..0000000000000000000000000000000000000000 --- a/doc/release/master.md +++ /dev/null @@ -1,33 +0,0 @@ -# How to push GitLab CE master branch to all remotes. - -The source code of GitLab is available on multiple servers (with GitLab.com as the canonical source). -Synchronization between the repo's is done by the lead developer if there is no rush. -This happens a few times per workday on average. -If somebody else with access to all repo's wants to do it the instructions are below. -This is just to distribute changes, not to make them. - -## Add this to `.bashrc` or [your dotfiles](https://github.com/dosire/dotfiles/commit/52803ce3ac60d57632164b7713ff0041e86fa26c) - -```bash -gpa () -{ - git push origin ${1:-master} && git push gh ${1:-master} && git push gl ${1:-master} -} -``` - -## Then add remotes to your local repo - -```bash -cd my-gitlab-ce-repo - -git remote add origin git@dev.gitlab.org:gitlab/gitlabhq.git -git remote add gh git@github.com:gitlabhq/gitlabhq.git -git remote add gl git@gitlab.com:gitlab-org/gitlab-ce.git -``` - -## Push to all remotes - -```bash -gpa -``` - diff --git a/doc/release/monthly.md b/doc/release/monthly.md deleted file mode 100644 index cfe01896d8fac30905a7ea7cf301aa8df793d39e..0000000000000000000000000000000000000000 --- a/doc/release/monthly.md +++ /dev/null @@ -1,212 +0,0 @@ -# Monthly Release - -NOTE: This is a guide used by the GitLab B.V. developers. - -It starts 7 working days before the release. -The release manager doesn't have to perform all the work but must ensure someone is assigned. -The current release manager must schedule the appointment of the next release manager. -The new release manager should create overall issue to track the progress. - -## Release Manager - -A release manager is selected that coordinates all releases the coming month, including the patch releases for previous releases. -The release manager has to make sure all the steps below are done and delegated where necessary. -This person should also make sure this document is kept up to date and issues are created and updated. - -## Take vacations into account - -The time is measured in weekdays to compensate for weekends. -Do everything on time to prevent problems due to rush jobs or too little testing time. -Make sure that you take into account any vacations of maintainers. -If the release is falling behind immediately warn the team. - -## Create an overall issue and follow it - -Create issue for GitLab CE project(internal). Name it "Release x.x.x" for easier searching. -Replace the dates with actual dates based on the number of workdays before the release. -All steps from issue template are explained below - -``` -Xth: (7 working days before the 22nd) - -- [ ] Code freeze -- [ ] Update the CE changelog (#LINK) -- [ ] Update the EE changelog (#LINK) -- [ ] Update the CI changelog (#LINK) -- [ ] Triage the omnibus-gitlab milestone - -Xth: (6 working days before the 22nd) - -- [ ] Merge CE master in to EE master via merge request (#LINK) -- [ ] Determine QA person and notify this person -- [ ] Check the tasks in [how to rc1 guide](howto_rc1.md) and delegate tasks if necessary -- [ ] Create CE, EE, CI RC1 versions (#LINK) - -Xth: (5 working days before the 22nd) - -- [ ] Do QA and fix anything coming out of it (#LINK) -- [ ] Close the omnibus-gitlab milestone -- [ ] Prepare the blog post (#LINK) - -Xth: (4 working days before the 22nd) - -- [ ] Update GitLab.com with rc1 (#LINK) (https://dev.gitlab.org/cookbooks/chef-repo/blob/master/doc/administration.md#deploy-the-package) -- [ ] Update ci.gitLab.com with rc1 (#LINK) (https://dev.gitlab.org/cookbooks/chef-repo/blob/master/doc/administration.md#deploy-the-package) -- [ ] Create regression issues (CE, CI) (#LINK) -- [ ] Tweet about rc1 (#LINK) - -Xth: (3 working days before the 22nd) - -- [ ] Merge CE stable branch into EE stable branch - -Xth: (2 working days before the 22nd) - -- [ ] Check that everyone is mentioned on the blog post (the reviewer should have done this one working day ago) -- [ ] Check that MVP is added to the mvp page (source/mvp/index.html in www-gitlab-com) - -Xth: (1 working day before the 22nd) - -- [ ] Create CE, EE, CI stable versions (#LINK) -- [ ] Create Omnibus tags and build packages -- [ ] Update GitLab.com with the stable version (#LINK) -- [ ] Update ci.gitLab.com with the stable version (#LINK) - -22nd: - -- [ ] Release CE, EE and CI (#LINK) - -``` - -- - - - -## Code Freeze - -Stop merging code in master, except for important bug fixes - -## Update changelog - -Any changes not yet added to the changelog are added by lead developer and in that merge request the complete team is -asked if there is anything missing. - -There are three changelogs that need to be updated: CE, EE and CI. - -## Create RC1 (CE, EE, CI) - -[Follow this How-to guide](howto_rc1.md) to create RC1. - -## Prepare CHANGELOG for next release - -Once the stable branches have been created, update the CHANGELOG in `master` with the upcoming version, usually X.X.X.pre. - -## QA - -Create issue on dev.gitlab.org `gitlab` repository, named "GitLab X.X QA" in order to keep track of the progress. - -Use the omnibus packages created for RC1 of Enterprise Edition using [this guide](https://dev.gitlab.org/gitlab/gitlab-ee/blob/master/doc/release/manual_testing.md). - -**NOTE** Upgrader can only be tested when tags are pushed to all repositories. Do not forget to confirm it is working before releasing. Note that in the issue. - -#### Fix anything coming out of the QA - -Create an issue with description of a problem, if it is quick fix fix it yourself otherwise contact the team for advice. - -**NOTE** If there is a problem that cannot be fixed in a timely manner, reverting the feature is an option! If the feature is reverted, -create an issue about it in order to discuss the next steps after the release. - -## Update GitLab.com with RC1 - -Use the omnibus EE packages created for RC1. -If there are big database migrations consider testing them with the production db on a VM. -Try to deploy in the morning. -It is important to do this as soon as possible, so we can catch any errors before we release the full version. - -## Create a regressions issue - -On [the GitLab CE issue tracker on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/issues/) create an issue titled "GitLab X.X regressions" add the following text: - -This is a meta issue to discuss possible regressions in this monthly release and any patch versions. -Please do not raise issues directly in this issue but link to issues that might warrant a patch release. -The decision to create a patch release or not is with the release manager who is assigned to this issue. -The release manager will comment here about the plans for patch releases. - -Assign the issue to the release manager and at mention all members of gitlab core team. If there are any known bugs in the release add them immediately. - -## Tweet about RC1 - -Tweet about the RC release: - -> GitLab x.x.0.rc1 is out. This release candidate is only suitable for testing. Please link regressions issues from LINK_TO_REGRESSION_ISSUE - -## Prepare the blog post - -1. Start with a complete copy of the [release blog template](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/doc/release_blog_template.md) and fill it out. -1. Make sure the blog post contains information about the GitLab CI release. -1. Check the changelog of CE and EE for important changes. -1. Also check the CI changelog -1. Add a proposed tweet text to the blog post WIP MR description. -1. Create a WIP MR for the blog post -1. Ask Dmitriy (or a team member with OS X) to add screenshots to the WIP MR. -1. Decide with core team who will be the MVP user. -1. Create WIP MR for adding MVP to MVP page on website -1. Add a note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible. -1. Create a merge request on [GitLab.com](https://gitlab.com/gitlab-com/www-gitlab-com/tree/master) -1. Assign to one reviewer who will fix spelling issues by editing the branch (either with a git client or by using the online editor) -1. Comment to the reviewer: '@person Please mention the whole team as soon as you are done (3 workdays before release at the latest)' - -## Create CE, EE, CI stable versions - -Get release tools - -``` -git clone git@dev.gitlab.org:gitlab/release-tools.git -cd release-tools -``` - -Bump version, create release tag and push to remotes: - -``` -bundle exec rake release["x.x.0"] -``` - -This will create correct version and tag and push to all CE, EE and CI remotes. - -Update [installation.md](/doc/install/installation.md) to the newest version in master. - - -## Create Omnibus tags and build packages - -Follow the [release doc in the Omnibus repository](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md). -This can happen before tagging because Omnibus uses tags in its own repo and SHA1's to refer to the GitLab codebase. - -## Update GitLab.com with the stable version - -- Deploy the package (should not need downtime because of the small difference with RC1) -- Deploy the package for ci.gitlab.com - -## Release CE, EE and CI - -__1. Publish packages for new release__ - -Update `downloads/index.html` and `downloads/archive/index.html` in `www-gitlab-com` repository. - -__2. Publish blog for new release__ - -Doublecheck the everyone has been mentioned in the blog post. -Merge the [blog merge request](#1-prepare-the-blog-post) in `www-gitlab-com` repository. - -__3. Tweet to blog__ - -Send out a tweet to share the good news with the world. -List the most important features and link to the blog post. - -Proposed tweet "Release of GitLab X.X & CI Y.Y! FEATURE, FEATURE and FEATURE <link-to-blog-post> #gitlab" - -Consider creating a post on Hacker News. - -## Release new AMIs - -[Follow this guide](https://dev.gitlab.org/gitlab/AMI/blob/master/README.md) - -## Create a WIP blogpost for the next release - -Create a WIP blogpost using [release blog template](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/doc/release_blog_template.md). diff --git a/doc/release/patch.md b/doc/release/patch.md deleted file mode 100644 index 4c7b471785f12085fe100cb2b0af8cd09480914a..0000000000000000000000000000000000000000 --- a/doc/release/patch.md +++ /dev/null @@ -1,55 +0,0 @@ -# Things to do when doing a patch release - -NOTE: This is a guide for GitLab developers. If you are trying to install GitLab see the latest stable [installation guide](install/installation.md) and if you are trying to upgrade, see the [upgrade guides](update). - -## When to do a patch release - -Do a patch release when there is a critical regression that needs to be addresses before the next monthly release. - -Otherwise include it in the monthly release and note there was a regression fix in the release announcement. - -## Release Procedure - -### Preparation - -1. Verify that the issue can be reproduced -1. Note in the 'GitLab X.X regressions' that you will create a patch -1. Create an issue on private GitLab development server -1. Name the issue "Release X.X.X CE and X.X.X EE", this will make searching easier -1. Fix the issue on a feature branch, do this on the private GitLab development server -1. If it is a security issue, then assign it to the release manager and apply a 'security' label -1. Consider creating and testing workarounds -1. After the branch is merged into master, cherry pick the commit(s) into the current stable branch -1. Make sure that the build has passed and all tests are passing -1. In a separate commit in the master branch update the CHANGELOG -1. For EE, update the CHANGELOG-EE if it is EE specific fix. Otherwise, merge the stable CE branch and add to CHANGELOG-EE "Merge community edition changes for version X.X.X" -1. Merge CE stable branch into EE stable branch - - -### Bump version - -Get release tools - -``` -git clone git@dev.gitlab.org:gitlab/release-tools.git -cd release-tools -``` - -Bump all versions in stable branch, even if the changes affect only EE, CE, or CI. Since all the versions are synced now, -it doesn't make sense to say upgrade CE to 7.2, EE to 7.3 and CI to 7.1. - -Create release tag and push to remotes: - -``` -bundle exec rake release["x.x.x"] -``` - -### Release - -1. [Build new packages with the latest version](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/release.md) -1. Apply the patch to GitLab.com and the private GitLab development server -1. Apply the patch to ci.gitLab.com and the private GitLab CI development server -1. Create and publish a blog post, see [patch release blog template](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/doc/patch_release_blog_template.md) -1. Send tweets about the release from `@gitlab`, tweet should include the most important feature that the release is addressing and link to the blog post -1. Note in the 'GitLab X.X regressions' issue that the patch was published (CE only) -1. [Create new AMIs](https://dev.gitlab.org/gitlab/AMI/blob/master/README.md) diff --git a/doc/release/security.md b/doc/release/security.md deleted file mode 100644 index 60bcfbb6da5b9f94e680076b268d5d0685225bee..0000000000000000000000000000000000000000 --- a/doc/release/security.md +++ /dev/null @@ -1,76 +0,0 @@ -# Things to do when doing an out-of-bound security release - -NOTE: This is a guide for GitLab developers. If you are trying to install GitLab see the latest stable [installation guide](install/installation.md) and if you are trying to upgrade, see the [upgrade guides](update). - -## When to do a security release - -Do a security release when there is a critical issue that needs to be addresses before the next monthly release. Otherwise include it in the monthly release and note there was a security fix in the release announcement. - -## Security vulnerability disclosure - -Please report suspected security vulnerabilities in private to , also see the [disclosure section on the GitLab.com website](http://about.gitlab.com/disclosure/). Please do NOT create publicly viewable issues for suspected security vulnerabilities. - -## Release Procedure - -1. Verify that the issue can be reproduced -1. Acknowledge the issue to the researcher that disclosed it -1. Inform the release manager that there needs to be a security release -1. Do the steps from [patch release document](doc/release/patch.md), starting with "Create an issue on private GitLab development server" -1. The MR with the security fix should get a 'security' label and be assigned to the release manager -1. Build the package for GitLab.com and do a deploy -1. Build the package for ci.gitLab.com and do a deploy -1. [Create new AMIs](https://dev.gitlab.org/gitlab/AMI/blob/master/README.md) -1. Create feature branches for the blog post on GitLab.com and link them from the code branch -1. Merge and publish the blog posts -1. Send tweets about the release from `@gitlabhq` -1. Send out an email to [the community google mailing list](https://groups.google.com/forum/#!forum/gitlabhq) -1. Post a signed copy of our complete announcement to [oss-security](http://www.openwall.com/lists/oss-security/) and request a CVE number. CVE is only needed for bugs that allow someone to own the server (Remote Code Execution) or access to code of projects they are not a member of. -1. Add the security researcher to the [Security Researcher Acknowledgments list](http://about.gitlab.com/vulnerability-acknowledgements/) -1. Thank the security researcher in an email for their cooperation -1. Update the blog post and the CHANGELOG when we receive the CVE number - -The timing of the code merge into master should be coordinated in advance. - -After the merge we strive to publish the announcements within 60 minutes. - -## Blog post template - -XXX Security Advisory for GitLab - -A recently discovered critical vulnerability in GitLab allows [unauthenticated API access|remote code execution|unauthorized access to repositories|XXX|PICKSOMETHING]. All users should update GitLab and gitlab-shell immediately. We [have|haven't|XXX|PICKSOMETHING|] heard of this vulnerability being actively exploited. - -### Version affected - -GitLab Community Edition XXX and lower - -GitLab Enterprise Edition XXX and lower - -### Fixed versions - -GitLab Community Edition XXX and up - -GitLab Enterprise Edition XXX and up - -### Impact - -On GitLab installations which use MySQL as their database backend it is possible for an attacker to assume the identity of any existing GitLab user in certain API calls. This attack can be performed by [unauthenticated|authenticated|XXX|PICKSOMETHING] users. - -### Workarounds - -If you are unable to upgrade you should apply the following patch and restart GitLab. - -XXX - -### Credit - -We want to thank XXX of XXX for the responsible disclosure of this vulnerability. - -## Email template - -We just announced a security advisory for GitLab at XXX - -Please contact us at support@gitlab.com if you have any questions. - -## Tweet template - -We just announced a security advisory for GitLab at XXX diff --git a/doc/security/README.md b/doc/security/README.md deleted file mode 100644 index 49dfa6eec76e68791623652f4a7cfb2cc7c3edbf..0000000000000000000000000000000000000000 --- a/doc/security/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Security - -- [Password length limits](password_length_limits.md) -- [Rack attack](rack_attack.md) -- [Web Hooks and insecure internal web services](webhooks.md) -- [Information exclusivity](information_exclusivity.md) diff --git a/doc/security/information_exclusivity.md b/doc/security/information_exclusivity.md deleted file mode 100644 index f8e7fc3fd0ec5f3b36a5c2791be7ebefe946f1e0..0000000000000000000000000000000000000000 --- a/doc/security/information_exclusivity.md +++ /dev/null @@ -1,9 +0,0 @@ -# Information exclusivity - -Git is a distributed version control system (DVCS). -This means that everyone that works with the source code has a local copy of the complete repository. -In GitLab every project member that is not a guest (so reporters, developers and masters) can clone the repository to get a local copy. -After obtaining this local copy the user can upload the full repository anywhere, including another project under their control or another server. -The consequence is that you can't build access controls that prevent the intentional sharing of source code by users that have access to the source code. -This is an inherent feature of a DVCS and all git management systems have this limitation. -Obviously you can take steps to prevent unintentional sharing and information destruction, this is why only some people are allowed to invite others and nobody can force push a protected branch. diff --git a/doc/security/password_length_limits.md b/doc/security/password_length_limits.md deleted file mode 100644 index d21b26a43e863fb859eef961ee127fd753147131..0000000000000000000000000000000000000000 --- a/doc/security/password_length_limits.md +++ /dev/null @@ -1,11 +0,0 @@ -# Custom password length limits - -If you want to enforce longer user passwords you can create an extra Devise initializer with the steps below. - -If you do not use the `devise_password_length.rb` initializer the password length is set to a minimum of 8 characters in `config/initializers/devise.rb`. - -```bash -cd /home/git/gitlab -sudo -u git -H cp config/initializers/devise_password_length.rb.example config/initializers/devise_password_length.rb -sudo -u git -H editor config/initializers/devise_password_length.rb # inspect and edit the new password length limits -``` diff --git a/doc/security/rack_attack.md b/doc/security/rack_attack.md deleted file mode 100644 index 92066997be89feaa54495284788070f754c50535..0000000000000000000000000000000000000000 --- a/doc/security/rack_attack.md +++ /dev/null @@ -1,25 +0,0 @@ -# Rack attack - -To prevent abusive clients doing damage GitLab uses rack-attack gem. - -If you installed or upgraded GitLab by following the official guides this should be enabled by default. - -If you are missing `config/initializers/rack_attack.rb` the following steps need to be taken in order to enable protection for your GitLab instance: - -1. In config/application.rb find and uncomment the following line: - - config.middleware.use Rack::Attack - -1. Rename `config/initializers/rack_attack.rb.example` to `config/initializers/rack_attack.rb`. - -1. Review the `paths_to_be_protected` and add any other path you need protecting. - -1. Restart GitLab instance. - -By default, user sign-in, user sign-up(if enabled) and user password reset is limited to 6 requests per minute. After trying for 6 times, client will have to wait for the next minute to be able to try again. These settings can be found in `config/initializers/rack_attack.rb` - -If you want more restrictive/relaxed throttle rule change the `limit` or `period` values. For example, more relaxed throttle rule will be if you set limit: 3 and period: 1.second(this will allow 3 requests per second). You can also add other paths to the protected list by adding to `paths_to_be_protected` variable. If you change any of these settings do not forget to restart your GitLab instance. - -In case you find throttling is not enough to protect you against abusive clients, rack-attack gem offers IP whitelisting, blacklisting, Fail2ban style filter and tracking. - -For more information on how to use these options check out [rack-attack README](https://github.com/kickstarter/rack-attack/blob/master/README.md). diff --git a/doc/security/webhooks.md b/doc/security/webhooks.md deleted file mode 100644 index 1e9d33e87c314a3b9353a623b4806114b47c5939..0000000000000000000000000000000000000000 --- a/doc/security/webhooks.md +++ /dev/null @@ -1,13 +0,0 @@ -# Web Hooks and insecure internal web services - -If you have non-GitLab web services running on your GitLab server or within its local network, these may be vulnerable to exploitation via Web Hooks. - -With [Web Hooks](../web_hooks/web_hooks.md), you and your project masters and owners can set up URLs to be triggered when specific things happen to projects. Normally, these requests are sent to external web services specifically set up for this purpose, that process the request and its attached data in some appropriate way. - -Things get hairy, however, when a Web Hook is set up with a URL that doesn't point to an external, but to an internal service, that may do something completely unintended when the web hook is triggered and the POST request is sent. - -Because Web Hook requests are made by the GitLab server itself, these have complete access to everything running on the server (http://localhost:123) or within the server's local network (http://192.168.1.12:345), even if these services are otherwise protected and inaccessible from the outside world. - -If a web service does not require authentication, Web Hooks can be used to trigger destructive commands by getting the GitLab server to make POST requests to endpoints like "http://localhost:123/some-resource/delete". - -To prevent this type of exploitation from happening, make sure that you are aware of every web service GitLab could potentially have access to, and that all of these are set up to require authentication for every potentially destructive command. Enabling authentication but leaving a default password is not enough. \ No newline at end of file diff --git a/doc/ssh/README.md b/doc/ssh/README.md deleted file mode 100644 index 0acb15896d379d0ac80a7b555d178dd9507984dd..0000000000000000000000000000000000000000 --- a/doc/ssh/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# SSH - -## SSH keys - -An SSH key allows you to establish a secure connection between your -computer and GitLab. - -Before generating an SSH key, check if your system already has one by -running `cat ~/.ssh/id_rsa.pub`. If you see a long string starting with -`ssh-rsa` or `ssh-dsa`, you can skip the ssh-keygen step. - -To generate a new SSH key, just open your terminal and use code below. The -ssh-keygen command prompts you for a location and filename to store the key -pair and for a password. When prompted for the location and filename, you -can press enter to use the default. - -It is a best practice to use a password for an SSH key, but it is not -required and you can skip creating a password by pressing enter. Note that -the password you choose here can't be altered or retrieved. - -```bash -ssh-keygen -t rsa -C "$your_email" -``` - -Use the code below to show your public key. - -```bash -cat ~/.ssh/id_rsa.pub -``` - -Copy-paste the key to the 'My SSH Keys' section under the 'SSH' tab in your -user profile. Please copy the complete key starting with `ssh-` and ending -with your username and host. - -Use code below to copy your public key to the clipboard. Depending on your -OS you'll need to use a different command: - -**Windows:** -```bash -clip < ~/.ssh/id_rsa.pub -``` - -**Mac:** -```bash -pbcopy < ~/.ssh/id_rsa.pub -``` - -**GNU/Linux (requires xclip):** -```bash -xclip -sel clip < ~/.ssh/id_rsa.pub -``` - -## Deploy keys - -Deploy keys allow read-only access to multiple projects with a single SSH -key. - -This is really useful for cloning repositories to your Continuous -Integration (CI) server. By using deploy keys, you don't have to setup a -dummy user account. - -If you are a project master or owner, you can add a deploy key in the -project settings under the section 'Deploy Keys'. Press the 'New Deploy -Key' button and upload a public SSH key. After this, the machine that uses -the corresponding private key has read-only access to the project. - -You can't add the same deploy key twice with the 'New Deploy Key' option. -If you want to add the same key to another project, please enable it in the -list that says 'Deploy keys from projects available to you'. All the deploy -keys of all the projects you have access to are available. This project -access can happen through being a direct member of the project, or through -a group. See `def accessible_deploy_keys` in `app/models/user.rb` for more -information. diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md deleted file mode 100644 index f9b6d37d8405fdab0411353642b905331179396c..0000000000000000000000000000000000000000 --- a/doc/system_hooks/system_hooks.md +++ /dev/null @@ -1,180 +0,0 @@ -# System hooks - -Your GitLab instance can perform HTTP POST requests on the following events: `project_create`, `project_destroy`, `user_add_to_team`, `user_remove_from_team`, `user_create`, `user_destroy`, `key_create`, `key_destroy`, `group_create`, `group_destroy`, `user_add_to_group` and `user_remove_from_group`. - -System hooks can be used, e.g. for logging or changing information in a LDAP server. - -## Hooks request example - -**Project created:** - -```json -{ - "created_at": "2012-07-21T07:30:54Z", - "event_name": "project_create", - "name": "StoreCloud", - "owner_email": "johnsmith@gmail.com", - "owner_name": "John Smith", - "path": "storecloud", - "path_with_namespace": "jsmith/storecloud", - "project_id": 74, - "project_visibility": "private", -} -``` - -**Project destroyed:** - -```json -{ - "created_at": "2012-07-21T07:30:58Z", - "event_name": "project_destroy", - "name": "Underscore", - "owner_email": "johnsmith@gmail.com", - "owner_name": "John Smith", - "path": "underscore", - "path_with_namespace": "jsmith/underscore", - "project_id": 73, - "project_visibility": "internal", -} -``` - -**New Team Member:** - -```json -{ - "created_at": "2012-07-21T07:30:56Z", - "event_name": "user_add_to_team", - "project_access": "Master", - "project_id": 74, - "project_name": "StoreCloud", - "project_path": "storecloud", - "user_email": "johnsmith@gmail.com", - "user_name": "John Smith", - "user_id": 41, - "project_visibility": "private", -} -``` - -**Team Member Removed:** - -```json -{ - "created_at": "2012-07-21T07:30:56Z", - "event_name": "user_remove_from_team", - "project_access": "Master", - "project_id": 74, - "project_name": "StoreCloud", - "project_path": "storecloud", - "user_email": "johnsmith@gmail.com", - "user_name": "John Smith", - "user_id": 41, - "project_visibility": "private", -} -``` - -**User created:** - -```json -{ - "created_at": "2012-07-21T07:44:07Z", - "email": "js@gitlabhq.com", - "event_name": "user_create", - "name": "John Smith", - "user_id": 41 -} -``` - -**User removed:** - -```json -{ - "created_at": "2012-07-21T07:44:07Z", - "email": "js@gitlabhq.com", - "event_name": "user_destroy", - "name": "John Smith", - "user_id": 41 -} -``` - -**Key added** - -```json -{ - "event_name": "key_create", - "created_at": "2014-08-18 18:45:16 UTC", - "username": "root", - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC58FwqHUbebw2SdT7SP4FxZ0w+lAO/erhy2ylhlcW/tZ3GY3mBu9VeeiSGoGz8hCx80Zrz+aQv28xfFfKlC8XQFpCWwsnWnQqO2Lv9bS8V1fIHgMxOHIt5Vs+9CAWGCCvUOAurjsUDoE2ALIXLDMKnJxcxD13XjWdK54j6ZXDB4syLF0C2PnAQSVY9X7MfCYwtuFmhQhKaBussAXpaVMRHltie3UYSBUUuZaB3J4cg/7TxlmxcNd+ppPRIpSZAB0NI6aOnqoBCpimscO/VpQRJMVLr3XiSYeT6HBiDXWHnIVPfQc03OGcaFqOit6p8lYKMaP/iUQLm+pgpZqrXZ9vB john@localhost", - "id": 4 -} -``` - -**Key removed** - -```json -{ - "event_name": "key_destroy", - "created_at": "2014-08-18 18:45:16 UTC", - "username": "root", - "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC58FwqHUbebw2SdT7SP4FxZ0w+lAO/erhy2ylhlcW/tZ3GY3mBu9VeeiSGoGz8hCx80Zrz+aQv28xfFfKlC8XQFpCWwsnWnQqO2Lv9bS8V1fIHgMxOHIt5Vs+9CAWGCCvUOAurjsUDoE2ALIXLDMKnJxcxD13XjWdK54j6ZXDB4syLF0C2PnAQSVY9X7MfCYwtuFmhQhKaBussAXpaVMRHltie3UYSBUUuZaB3J4cg/7TxlmxcNd+ppPRIpSZAB0NI6aOnqoBCpimscO/VpQRJMVLr3XiSYeT6HBiDXWHnIVPfQc03OGcaFqOit6p8lYKMaP/iUQLm+pgpZqrXZ9vB john@localhost", - "id": 4 -} -``` - -**Group created:** - -```json -{ - "created_at": "2012-07-21T07:30:54Z", - "event_name": "group_create", - "name": "StoreCloud", - "owner_email": "johnsmith@gmail.com", - "owner_name": "John Smith", - "path": "storecloud", - "group_id": 78 -} -``` - -**Group removed:** - -```json -{ - "created_at": "2012-07-21T07:30:54Z", - "event_name": "group_destroy", - "name": "StoreCloud", - "owner_email": "johnsmith@gmail.com", - "owner_name": "John Smith", - "path": "storecloud", - "group_id": 78 -} -``` - -**New Group Member:** - -```json -{ - "created_at": "2012-07-21T07:30:56Z", - "event_name": "user_add_to_group", - "group_access": "Master", - "group_id": 78, - "group_name": "StoreCloud", - "group_path": "storecloud", - "user_email": "johnsmith@gmail.com", - "user_name": "John Smith", - "user_id": 41 -} -``` -**Group Member Removed:** - -```json -{ - "created_at": "2012-07-21T07:30:56Z", - "event_name": "user_remove_from_group", - "group_access": "Master", - "group_id": 78, - "group_name": "StoreCloud", - "group_path": "storecloud", - "user_email": "johnsmith@gmail.com", - "user_name": "John Smith", - "user_id": 41 -} -``` diff --git a/doc/update/2.6-to-3.0.md b/doc/update/2.6-to-3.0.md deleted file mode 100644 index 4827ef9501a112732c0eb5ac5726ceef7e72aabb..0000000000000000000000000000000000000000 --- a/doc/update/2.6-to-3.0.md +++ /dev/null @@ -1,62 +0,0 @@ -# From 2.6 to 3.0 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/2.6-to-3.0.md) for the most up to date instructions.* - -## 1. Stop server & resque - - sudo service gitlab stop - -## 2. Update code & db - - -```bash -# Get latest code -git fetch origin -git checkout v3.0.3 - - -# Install libs -sudo -u gitlab bundle install --without development test postgres - -# update db -sudo -u gitlab bundle exec rake db:migrate RAILS_ENV=production - -# !!! Config should be replaced with a new one. Check it after replace -cp config/gitlab.yml.example config/gitlab.yml - -# update Gitolite hooks - -# Gitolite v2: -sudo cp ./lib/hooks/post-receive /home/git/share/gitolite/hooks/common/post-receive -sudo chown git:git /home/git/share/gitolite/hooks/common/post-receive - -# Gitolite v3: -sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive -sudo chown git:git /home/git/.gitolite/hooks/common/post-receive - -# set valid path to hooks in gitlab.yml in git_host section -# like this -git_host: - # Gitolite 2 - hooks_path: /home/git/share/gitolite/hooks - # Gitolite 3 - hooks_path: /home/git/.gitolite/hooks/ - - -# Make some changes to Gitolite config -# For more information visit https://github.com/gitlabhq/gitlabhq/pull/1719 - -# Gitolite v2 -sudo -u git -H sed -i 's/\(GL_GITCONFIG_KEYS\s*=>*\s*\).\{2\}/\\1"\.\*"/g' /home/git/.gitolite.rc - -# gitlite v3 -sudo -u git -H sed -i "s/\(GIT_CONFIG_KEYS\s*=>*\s*\).\{2\}/\\1'\.\*'/g" /home/git/.gitolite.rc - - -# Check app status -sudo -u gitlab bundle exec rake gitlab:app:status RAILS_ENV=production - -``` - -## 3. Start all - - sudo service gitlab start diff --git a/doc/update/2.9-to-3.0.md b/doc/update/2.9-to-3.0.md deleted file mode 100644 index f4a997a8c5e5676b2f33937e2331f52e06a98b8d..0000000000000000000000000000000000000000 --- a/doc/update/2.9-to-3.0.md +++ /dev/null @@ -1,37 +0,0 @@ -# From 2.9 to 3.0 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/2.9-to-3.0.md) for the most up to date instructions.* - -## 1. Stop server & resque - - sudo service gitlab stop - -## 2. Follow instructions - -```bash - -# Get latest code -sudo -u gitlab -H git fetch origin -sudo -u gitlab -H git checkout v3.0.3 - -# Install gems -sudo -u gitlab -H bundle install --without development test postgres - -# Migrate db -sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production - -# Make some changes to gitolite v3 config -# For more information visit https://github.com/gitlabhq/gitlabhq/pull/1719 - -# Gitolite version 3 -sudo -u git -H sed -i "s/\(GIT_CONFIG_KEYS\s*=>*\s*\).\{2\}/\\1'\.\*'/g" /home/git/.gitolite.rc - -# If you still use gitolite v2 -sudo -u git -H sed -i 's/\(GL_GITCONFIG_KEYS\s*=>*\s*\).\{2\}/\\1"\.\*"/g' /home/git/.gitolite.rc - -# Check APP Status -sudo -u gitlab -H bundle exec rake gitlab:app:status RAILS_ENV=production -``` - -## 3. Start all - - sudo service gitlab start diff --git a/doc/update/3.0-to-3.1.md b/doc/update/3.0-to-3.1.md deleted file mode 100644 index a30485c42f799a396141d9c546801b2c3e266a0e..0000000000000000000000000000000000000000 --- a/doc/update/3.0-to-3.1.md +++ /dev/null @@ -1,97 +0,0 @@ -# From 3.0 to 3.1 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/3.0-to-3.1.md) for the most up to date instructions.* - -**IMPORTANT!** - -In this release **we moved Resque jobs under own gitlab namespace** - -Despite a lot of advantages it requires from our users to **replace gitolite post-receive hook with new one**. - -Most of projects has post-receive file as symlink to gitolite `/home/git/.gitolite/hooks/post-receive`. But some of them may have a real file. In this case you should rewrite it with symlink to gitolite hook. - -I wrote a bash script which will do it automatically for you. Just make sure all path inside is valid for you - -## 1. Stop server & resque - - sudo service gitlab stop - -## 2. Update GitLab - -```bash -# Get latest code -sudo -u gitlab -H git fetch -sudo -u gitlab -H git checkout v3.1.0 - -# Install new charlock_holmes -sudo gem install charlock_holmes --version '0.6.9' - -# Install gems for MySQL -sudo -u gitlab -H bundle install --without development test postgres sqlite - - -# Migrate db -sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production - -``` - -## 3. Update post-receive hooks - -### Gitolite 3 - -Step 1: Rewrite post-receive hook - -```bash -# Rewrite hook for gitolite 3 -sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive -sudo chown git:git /home/git/.gitolite/hooks/common/post-receive -``` - -Step 2: Rewrite hooks in all projects to symlink gitolite hook - -```bash -# 1. Check for valid path -sudo -u gitlab -H vim lib/support/rewrite-hooks.sh - -# 2. Run script -sudo -u git -H lib/support/rewrite-hooks.sh -``` - -### Gitolite v2 - -Step 1: rewrite post-receive hook for gitolite 2 - -``` -sudo cp ./lib/hooks/post-receive /home/git/share/gitolite/hooks/common/post-receive -sudo chown git:git /home/git/share/gitolite/hooks/common/post-receive -``` - -Step 2: Replace symlinks in project to valid place - - #!/bin/bash - src="/home/git/repositories" - for dir in `ls "$src/"` - do - if [ -d "$src/$dir" ]; then - - if [ "$dir" = "gitolite-admin.git" ] - then - continue - fi - - project_hook="$src/$dir/hooks/post-receive" - gitolite_hook="/home/git/share/gitolite/hooks/common/post-receive" - - ln -s -f $gitolite_hook $project_hook - fi - done - -## 4. Check app status - -```bash -# Check APP Status -sudo -u gitlab -H bundle exec rake gitlab:app:status RAILS_ENV=production -``` - -## 5. Start all - - sudo service gitlab start diff --git a/doc/update/3.1-to-4.0.md b/doc/update/3.1-to-4.0.md deleted file mode 100644 index f1ef4df4744cae9304762ce956b8333346a12ee1..0000000000000000000000000000000000000000 --- a/doc/update/3.1-to-4.0.md +++ /dev/null @@ -1,90 +0,0 @@ -# From 3.1 to 4.0 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/3.1-to-4.0.md) for the most up to date instructions.* - -## Important changes - -- Support for SQLite was dropped -- Support for Gitolite 2 was dropped -- Projects are organized in namespaces -- The GitLab post-receive hook needs to be updated -- The configuration file needs to be updated -- Availability of `python2` executable - -Most of projects has post-receive file as symlink to Gitolite `/home/git/.gitolite/hooks/post-receive`. But some of them may have a real file. In this case you should rewrite it with symlink to Gitolite hook. - -I wrote a bash script which will do it automatically for you. Just make sure all path inside is valid for you - -## 1. Stop GitLab & Resque - - sudo service gitlab stop - -## 2. Update GitLab - -```bash - -# Get latest code -sudo -u gitlab -H git fetch -sudo -u gitlab -H git checkout 4-0-stable - -# Install gems for MySQL -sudo -u gitlab -H bundle install --without development test postgres - -# Update repos permissions -sudo chmod -R ug+rwXs /home/git/repositories/ -sudo chown -R git:git /home/git/repositories/ - -# Migrate db -sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production - -# Enable namespaces (**Warning!** All projects in groups will be moved to subdirectories) -sudo -u gitlab -H bundle exec rake gitlab:enable_namespaces RAILS_ENV=production - -``` - -## 3. Update post-receive hooks (Requires Gitolite v3 ) - -Step 1: Rewrite post-receive hook - -```bash -sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive -sudo chown git:git /home/git/.gitolite/hooks/common/post-receive -``` - -Step 2: Update project hooks to be symlinks to the Gitolite hook - -```bash -# 1. Check paths in script -sudo -u gitlab -H vim lib/support/rewrite-hooks.sh - -# 2. Run script -sudo -u git -H lib/support/rewrite-hooks.sh -``` - -## 4. Replace config with new one - - # backup old one - sudo -u gitlab -H cp config/gitlab.yml config/gitlab.yml.old - - # copy new one - sudo -u gitlab -H cp config/gitlab.yml.example config/gitlab.yml - - # edit it - sudo -u gitlab -H vim config/gitlab.yml - -## 5. Disable ssh known_host check for own domain - - echo "Host localhost - StrictHostKeyChecking no - UserKnownHostsFile=/dev/null" | sudo tee -a /etc/ssh/ssh_config - - echo "Host YOUR_DOMAIN_NAME - StrictHostKeyChecking no - UserKnownHostsFile=/dev/null" | sudo tee -a /etc/ssh/ssh_config - -## 6. Check GitLab's status - - sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production - -## 7. Start GitLab & Resque - - sudo service gitlab start diff --git a/doc/update/4.0-to-4.1.md b/doc/update/4.0-to-4.1.md deleted file mode 100644 index d89d523591706ce0830300c77e17f1a5460dfcf7..0000000000000000000000000000000000000000 --- a/doc/update/4.0-to-4.1.md +++ /dev/null @@ -1,56 +0,0 @@ -# From 4.0 to 4.1 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/4.0-to-4.1.md) for the most up to date instructions.* - -## Important changes - -- Resque replaced with Sidekiq -- New options for configuration file added -- Init.d script should be updated -- **requires ruby1.9.3-p327** - -## 1. Stop GitLab & Resque - - sudo service gitlab stop - -## 2. Update GitLab - -```bash -# Set the working directory -cd /home/gitlab/gitlab/ - -# Get latest code -sudo -u gitlab -H git fetch -sudo -u gitlab -H git checkout 4-1-stable - -# Install gems for MySQL -sudo -u gitlab -H bundle install --without development test postgres - -# Migrate db -sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production - -``` - -## 3. Replace init.d script with a new one - -``` -# backup old one -sudo mv /etc/init.d/gitlab /etc/init.d/gitlab.old - -# get new one using sidekiq -sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/4-1-stable/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab - -``` - -## 4. Check GitLab's status - - sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production - - -## 5. Start GitLab & Sidekiq - - sudo service gitlab start - -## 6. Remove old init.d script - - sudo rm /etc/init.d/gitlab.old diff --git a/doc/update/4.1-to-4.2.md b/doc/update/4.1-to-4.2.md deleted file mode 100644 index 6fe4412ff90afaddee77e1b266b42e0fd1ac42a3..0000000000000000000000000000000000000000 --- a/doc/update/4.1-to-4.2.md +++ /dev/null @@ -1,36 +0,0 @@ -# From 4.1 to 4.2 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/4.1-to-4.2.md) for the most up to date instructions.* - -## 1. Stop server & Resque - - sudo service gitlab stop - -## 2. Update code & DB - -```bash - -#Set the working directory -cd /home/gitlab/gitlab/ - -# Get latest code -sudo -u gitlab -H git fetch - -sudo -u gitlab -H git checkout 4-2-stable - -# Install libs -sudo -u gitlab -H bundle install --without development test postgres --deployment - -# update db -sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production - -``` - -## 3. Check GitLab's status - -```bash -sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production -``` - -## 4. Start all - - sudo service gitlab start diff --git a/doc/update/4.2-to-5.0.md b/doc/update/4.2-to-5.0.md deleted file mode 100644 index f9faf65f9525d29367cc7fc21772ac5eb8cc2e7b..0000000000000000000000000000000000000000 --- a/doc/update/4.2-to-5.0.md +++ /dev/null @@ -1,211 +0,0 @@ -# From 4.2 to 5.0 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/4.2-to-5.0.md) for the most up to date instructions.* - -## Warning - -GitLab 5.0 is affected by critical security vulnerability CVE-2013-4490. - -## Important changes - -- We don't use `gitlab` user any more. Everything will be moved to `git` user -- Self signed SSL certificates are not supported until GitLab 5.1 -- **requires ruby1.9.3** - -## 0. Stop GitLab - - sudo service gitlab stop - -## 1. add bash to git user - -``` -sudo chsh -s /bin/bash git -``` - -## 2. git clone gitlab-shell - -``` -cd /home/git/ -sudo -u git -H git clone https://github.com/gitlabhq/gitlab-shell.git /home/git/gitlab-shell -``` - -## 3. setup gitlab-shell - -```bash -# chmod all repos and files under git -sudo chown git:git -R /home/git/repositories/ - -# login as git -sudo su git -cd /home/git/gitlab-shell -git checkout v1.1.0 - -# copy config -cp config.yml.example config.yml - -# change URL to GitLab instance -# ! make sure the URL ends with '/' like 'https://gitlab.example/' -vim config.yml - -# rewrite hooks -./support/rewrite-hooks.sh - -# check ruby version for git user ( 1.9 required!! ) -# GitLab shell requires system ruby 1.9 -ruby -v - -# exit from git user -exit -``` - -## 4. Copy GitLab instance to git user - -```bash -sudo cp -R /home/gitlab/gitlab /home/git/gitlab -sudo chown git:git -R /home/git/gitlab -sudo rm -rf /home/gitlab/gitlab-satellites - -# if exists -sudo rm /tmp/gitlab.socket -``` - -## 5. Update GitLab to recent version - -```bash -cd /home/git/gitlab - -# backup current config -sudo -u git -H cp config/gitlab.yml config/gitlab.yml.old - -sudo -u git -H git fetch -sudo -u git -H git checkout 5-0-stable - -# replace config with recent one -sudo -u git -H cp config/gitlab.yml.example config/gitlab.yml - -# edit it -sudo -u git -H vim config/gitlab.yml - - -sudo -u git -H bundle install --without development test postgres --deployment -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake gitlab:shell:setup RAILS_ENV=production -sudo -u git -H bundle exec rake gitlab:shell:build_missing_projects RAILS_ENV=production - -sudo -u git -H mkdir -p /home/git/gitlab-satellites -sudo -u git -H bundle exec rake gitlab:satellites:create RAILS_ENV=production - -# migrate wiki to git -sudo -u git -H bundle exec rake gitlab:wiki:migrate RAILS_ENV=production - - -# check permissions for /home/git/.ssh/ -sudo -u git -H chmod 700 /home/git/.ssh -sudo -u git -H chmod 600 /home/git/.ssh/authorized_keys - -# check permissions for /home/git/gitlab/ -sudo chown -R git /home/git/gitlab/log/ -sudo chown -R git /home/git/gitlab/tmp/ -sudo chmod -R u+rwX /home/git/gitlab/log/ -sudo chmod -R u+rwX /home/git/gitlab/tmp/ -sudo -u git -H mkdir -p /home/git/gitlab/tmp/pids/ -sudo chmod -R u+rwX /home/git/gitlab/tmp/pids - -``` - -## 6. Update init.d script and Nginx config - -```bash -# init.d -sudo rm /etc/init.d/gitlab -sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-0-stable/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab - -# unicorn -sudo -u git -H cp /home/git/gitlab/config/unicorn.rb /home/git/gitlab/config/unicorn.rb.old -sudo -u git -H cp /home/git/gitlab/config/unicorn.rb.example /home/git/gitlab/config/unicorn.rb - -# Nginx -# Replace path from '/home/gitlab/' to '/home/git/' -sudo vim /etc/nginx/sites-enabled/gitlab -sudo service nginx restart - -``` - -## 7. Start GitLab instance - -``` -sudo service gitlab start - -# check if unicorn and sidekiq started -# If not try to logout, also check replaced path from '/home/gitlab/' to '/home/git/' -# in Nginx, unicorn, init.d etc -ps aux | grep unicorn -ps aux | grep sidekiq - -``` - -## 8. Check installation - - -```bash -# In 5-10 seconds lets check gitlab-shell -sudo -u git -H /home/git/gitlab-shell/bin/check - -# Example of success output -# Check GitLab API access: OK -# Check directories and files: -# /home/git/repositories: OK -# /home/git/.ssh/authorized_keys: OK - - -# Now check GitLab instance -sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -``` - -## 9. Cleanup - -**If everything works as expected you can cleanup some old things** -Recommend you wait a bit and do a backup before completing the following. - -```bash -# remove GitLab user from system -sudo userdel -r gitlab - -cd /home/git - -# cleanup .profile -## remove text from .profile added during gitolite installation: -## PATH=\$PATH:/home/git/bin -## export PATH -## to see what a clean .profile for new users on your system would look like see /etc/skel/.profile -sudo -u git -H vim .profile - -# remove gitolite -sudo rm -R bin -sudo rm -Rf gitolite -sudo rm -R .gitolite -sudo rm .gitolite.rc -sudo rm -f gitlab.pub -sudo rm projects.list - -# reset tmp folders -sudo service gitlab stop -cd /home/git/gitlab -sudo rm -R tmp -sudo -u git -H mkdir tmp -sudo chmod -R u+rwX tmp/ - -# create directory for pids, make sure GitLab can write to it -sudo -u git -H mkdir tmp/pids/ -sudo chmod -R u+rwX tmp/pids/ - -# if you are already running a newer version of GitLab check that installation guide for other tmp folders you need to create - -# reboot system -sudo reboot - -# login, check that GitLab is running fine -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production -``` diff --git a/doc/update/5.0-to-5.1.md b/doc/update/5.0-to-5.1.md deleted file mode 100644 index 9fbd1f88515eb62ec289c375df647c1458bd0d32..0000000000000000000000000000000000000000 --- a/doc/update/5.0-to-5.1.md +++ /dev/null @@ -1,91 +0,0 @@ -# From 5.0 to 5.1 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/5.0-to-5.1.md) for the most up to date instructions.* - -## Warning - -GitLab 5.1 is affected by critical security vulnerability CVE-2013-4490. - -## Release notes - -- `unicorn` replaced with `puma` -- merge request cached diff will be truncated - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch -sudo -u git -H git checkout 5-1-stable -``` - -## 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.3.0 -# replace your old config with the new one -sudo -u git -H mv config.yml config.yml.old -sudo -u git -H cp config.yml.example config.yml -# edit options to match old config -sudo -u git -H vi config.yml -``` - -## 4. Install libs, migrations etc - -```bash -cd /home/git/gitlab -sudo rm tmp/sockets/gitlab.socket -sudo -u git -H cp config/puma.rb.example config/puma.rb - -sudo -u git -H bundle install --without development test postgres --deployment -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_merge_requests RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -``` - -## 5. Update init.d script with a new one - -```bash -# init.d -sudo rm /etc/init.d/gitlab -sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-1-stable/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab -``` - -## 6. MySQL grant privileges - -Only if you are using MySQL: - -```bash -mysql -u root -p -mysql> GRANT LOCK TABLES ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; -mysql> \q -``` - -## 7. Start application - - sudo service gitlab start - -## 8. Check installation - - -```bash -# In 5-10 seconds lets check gitlab-shell -sudo -u git -H /home/git/gitlab-shell/bin/check - -# Example of success output -# Check GitLab API access: OK -# Check directories and files: -# /home/git/repositories: OK -# /home/git/.ssh/authorized_keys: OK - - -# Now check gitlab instance -sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -``` diff --git a/doc/update/5.1-to-5.2.md b/doc/update/5.1-to-5.2.md deleted file mode 100644 index cf9c4e4f770437662929f670e1dfc4a396a697ee..0000000000000000000000000000000000000000 --- a/doc/update/5.1-to-5.2.md +++ /dev/null @@ -1,104 +0,0 @@ -# From 5.1 to 5.2 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/5.1-to-5.2.md) for the most up to date instructions.* - -## Warning - -GitLab 5.2 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. - -## 0. Backup - -It's useful to make a backup just in case things go south: -(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch -sudo -u git -H git checkout 5-2-stable -``` - -## 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.4.0 -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -#PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -``` - -## 5. Update config files - -- Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-2-stable/config/gitlab.yml.example but with your settings. -- Make `/home/git/gitlab/config/puma.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-2-stable/config/puma.rb.example but with your settings. - -## 6. Update Init script - -```bash -cd /home/git/gitlab -sudo rm /etc/init.d/gitlab -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab -``` - -## 7. Create uploads directory - -```bash -cd /home/git/gitlab -sudo -u git -H mkdir public/uploads -sudo chmod -R u+rwX public/uploads -``` - -## 8. Start application - - sudo service gitlab start - sudo service nginx restart - -## 9. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (5.1) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 5.0 to 5.1](5.0-to-5.1.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/5.1-to-5.4.md b/doc/update/5.1-to-5.4.md deleted file mode 100644 index 97a98ede070d9abbe4d3cf729b5a46fd6d444b1b..0000000000000000000000000000000000000000 --- a/doc/update/5.1-to-5.4.md +++ /dev/null @@ -1,100 +0,0 @@ -# From 5.1 to 5.4 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/5.1-to-5.4.md) for the most up to date instructions.* - -Also works starting from 5.2. - -## 0. Backup - -It's useful to make a backup just in case things go south (with MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version): - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch -sudo -u git -H git checkout 5-4-stable # Latest version of 5-4-stable addresses CVE-2013-4489 -``` - -## 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.7.9 # Addresses multiple critical security vulnerabilities -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -#PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -``` - -## 5. Update config files - -- Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-4-stable/config/gitlab.yml.example but with your settings. -- Make `/home/git/gitlab/config/puma.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-4-stable/config/puma.rb.example but with your settings. - -## 6. Update Init script - -```bash -sudo rm /etc/init.d/gitlab -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab -``` - -## 7. Create uploads directory - -```bash -cd /home/git/gitlab -sudo -u git -H mkdir public/uploads -sudo chmod -R u+rwX public/uploads -``` - -## 8. Start application - - sudo service gitlab start - sudo service nginx restart - -## 9. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (5.3) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 5.2 to 5.3](5.2-to-5.3.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/5.1-to-6.0.md b/doc/update/5.1-to-6.0.md deleted file mode 100644 index a3fdd92bd2f17aac20f2b313c36a460ea069bfd8..0000000000000000000000000000000000000000 --- a/doc/update/5.1-to-6.0.md +++ /dev/null @@ -1,216 +0,0 @@ -# From 5.1 to 6.0 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/5.1-to-6.0.md) for the most up to date instructions.* - -## Warning - -GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. - -## Deprecations - -### Global projects - -The root (global) namespace for projects is deprecated. - -So you need to move all your global projects under groups or users manually before update or they will be automatically moved to the project owner namespace during the update. When a project is moved all its members will receive an email with instructions how to update their git remote URL. Please make sure you disable sending email when you do a test of the upgrade. - -### Teams - -We introduce group membership in 6.0 as a replacement for teams. - -The old combination of groups and teams was confusing for a lot of people. - -And when the members of a team where changed this wasn't reflected in the project permissions. - -In GitLab 6.0 you will be able to add members to a group with a permission level for each member. - -These group members will have access to the projects in that group. - -Any changes to group members will immediately be reflected in the project permissions. - -You can even have multiple owners for a group, greatly simplifying administration. - -## 0. Backup & prepare for update - -It's useful to make a backup just in case things go south: -(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -The migrations in this update are very sensitive to incomplete or inconsistent data. If you have a long-running GitLab installation and some of the previous upgrades did not work out 100% correct this may bite you now. The following can help you have a more smooth upgrade. - -### Find projects with invalid project names - -#### MySQL -Login to MySQL: - - mysql -u root -p - -Find projects with invalid names: - -```bash -mysql> use gitlabhq_production; - -# find projects with invalid first char, projects must start with letter -mysql> select name from projects where name REGEXP '^[^A-Za-z]'; - -# find projects with other invalid chars -## names must only contain alphanumeric chars, underscores, spaces, periods, and dashes -mysql> select name from projects where name REGEXP '[^a-zA-Z0-9_ .-]+'; -``` - -If any projects have invalid names try correcting them from the web interface before starting the upgrade. -If correcting them from the web interface fails you can correct them using MySQL: - -```bash -# e.g. replace invalid / with allowed _ -mysql> update projects set name = REPLACE(name,'/','_'); -# repeat for all invalid chars found in project names -``` - -#### PostgreSQL -Make sure all project names start with a letter and only contain alphanumeric chars, underscores, spaces, periods, and dashes (a-zA-Z0-9_ .-). - -### Find other common errors - -``` -cd /home/git/gitlab -# Start rails console -sudo -u git -H bin/rails console production - -# Make sure none of the following rails commands return results - -# All project owners should have an owner: -Project.all.select { |project| project.owner.blank? } - -# Every user should have a namespace: -User.all.select { |u| u.namespace.blank? } - -# Projects in the global namespace should not conflict with projects in the owner namespace: -Project.where(namespace_id: nil).select { |p| Project.where(path: p.path, namespace_id: p.owner.try(:namespace).try(:id)).present? } -``` - -If any of the above rails commands returned results other than `=> []` try correcting the issue from the web interface. - -If you find projects without an owner (first rails command above), correct it. For MySQL setups: - -```bash -# get your user id -mysql> select id, name from users order by name; - -# set yourself as owner of project -# replace your_user_id with your user id and bad_project_id with the project id from the rails command -mysql> update projects set creator_id=your_user_id where id=bad_project_id; -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch -sudo -u git -H git checkout 6-0-stable -``` - -## 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.7.9 -``` - -## 4. Install additional packages - -```bash -# For reStructuredText markup language support install required package: -sudo apt-get install python-docutils -``` - -## 5. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -#PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_groups RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_global_projects RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_keys RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_inline_notes RAILS_ENV=production -sudo -u git -H bundle exec rake gitlab:satellites:create RAILS_ENV=production - -# Clear redis cache -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production - -# Clear and precompile assets -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production - -#Add dealing with newlines for editor -sudo -u git -H git config --global core.autocrlf input -``` - -## 6. Update config files - -Note: We switched from Puma in GitLab 5.x to unicorn in GitLab 6.0. - -- Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-0-stable/config/gitlab.yml.example but with your settings. -- Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-0-stable/config/unicorn.rb.example but with your settings. - -## 7. Update Init script - -```bash -cd /home/git/gitlab -sudo rm /etc/init.d/gitlab -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab -``` - -## 8. Create uploads directory - -```bash -cd /home/git/gitlab -sudo -u git -H mkdir -p public/uploads -sudo chmod -R u+rwX public/uploads -``` - -## 9. Start application - - sudo service gitlab start - sudo service nginx restart - -## 10. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (5.1) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 5.0 to 5.1](5.0-to-5.1.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/5.2-to-5.3.md b/doc/update/5.2-to-5.3.md deleted file mode 100644 index 27613aeda07e536a8b170480a39df9906addd7c8..0000000000000000000000000000000000000000 --- a/doc/update/5.2-to-5.3.md +++ /dev/null @@ -1,86 +0,0 @@ -# From 5.2 to 5.3 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/5.2-to-5.3.md) for the most up to date instructions.* - -## Warning - -GitLab 5.3 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. - -## 0. Backup - -It's useful to make a backup just in case things go south (with MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version): - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch -sudo -u git -H git checkout 5-3-stable -``` - -## 3. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -#PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -``` - -## 4. Update config files - -- Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-3-stable/config/gitlab.yml.example but with your settings. -- Make `/home/git/gitlab/config/puma.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-3-stable/config/puma.rb.example but with your settings. - -## 5. Update Init script - -```bash -sudo rm /etc/init.d/gitlab -sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-3-stable/lib/support/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab -``` - -## 6. Start application - - sudo service gitlab start - sudo service nginx restart - -## 7. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (5.2) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 5.1 to 5.2](5.1-to-5.2.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/5.3-to-5.4.md b/doc/update/5.3-to-5.4.md deleted file mode 100644 index 577b9a585ffb47407bd22ec2e5b8f1c5913996fc..0000000000000000000000000000000000000000 --- a/doc/update/5.3-to-5.4.md +++ /dev/null @@ -1,90 +0,0 @@ -# From 5.3 to 5.4 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/5.3-to-5.4.md) for the most up to date instructions.* - -## 0. Backup - -It's useful to make a backup just in case things go south (with MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version): - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch -sudo -u git -H git checkout 5-4-stable # Latest version of 5-4-stable addresses CVE-2013-4489 -``` - -## 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.7.9 # Addresses multiple critical security vulnerabilities -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -#PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -``` - -## 5. Update config files - -- Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-4-stable/config/gitlab.yml.example but with your settings. -- Make `/home/git/gitlab/config/puma.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/5-4-stable/config/puma.rb.example but with your settings. - -## 6. Update Init script - -```bash -sudo rm /etc/init.d/gitlab -sudo curl -L --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-4-stable/lib/support/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab -``` - -## 7. Start application - - sudo service gitlab start - sudo service nginx restart - -## 8. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (5.3) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 5.2 to 5.3](5.2-to-5.3.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/5.4-to-6.0.md b/doc/update/5.4-to-6.0.md deleted file mode 100644 index d9c6d9bfb91cbc9b56f6865ee0761c5ba6e50af0..0000000000000000000000000000000000000000 --- a/doc/update/5.4-to-6.0.md +++ /dev/null @@ -1,149 +0,0 @@ -# From 5.4 to 6.0 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/5.4-to-6.0.md) for the most up to date instructions.* - -## Warning - -GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. - -**You need to follow this guide first, before updating past 6.0, as it contains critical migration steps that are only present -in the `6-0-stable` branch** - -## Deprecations - -### Global projects - -The root (global) namespace for projects is deprecated. - -So you need to move all your global projects under groups or users manually before update or they will be automatically moved to the project owner namespace during the update. When a project is moved all its members will receive an email with instructions how to update their git remote URL. Please make sure you disable sending email when you do a test of the upgrade. - -### Teams - -We introduce group membership in 6.0 as a replacement for teams. - -The old combination of groups and teams was confusing for a lot of people. - -And when the members of a team where changed this wasn't reflected in the project permissions. - -In GitLab 6.0 you will be able to add members to a group with a permission level for each member. - -These group members will have access to the projects in that group. - -Any changes to group members will immediately be reflected in the project permissions. - -You can even have multiple owners for a group, greatly simplifying administration. - -## 0. Backup - -It's useful to make a backup just in case things go south (with MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version): - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch -sudo -u git -H git checkout 6-0-stable -``` - -## 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.7.9 -``` - -## 4. Install additional packages - -```bash -# For reStructuredText markup language support install required package: -sudo apt-get install python-docutils -``` - -## 5. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_groups RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_global_projects RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_keys RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_inline_notes RAILS_ENV=production -sudo -u git -H bundle exec rake gitlab:satellites:create RAILS_ENV=production - -# Clear redis cache -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production - -# Clear and precompile assets -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -``` - -## 6. Update config files - -Note: We switched from Puma in GitLab 5.4 to unicorn in GitLab 6.0. - -- Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/gitlab.yml.example but with your settings. -- Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/unicorn.rb.example but with your settings. - -## 7. Update Init script - -```bash -sudo rm /etc/init.d/gitlab -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -sudo chmod +x /etc/init.d/gitlab -``` - -## 8. Start application - - sudo service gitlab start - sudo service nginx restart - -## 9. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Troubleshooting - -The migrations in this update are very sensitive to incomplete or inconsistent data. If you have a long-running GitLab installation and some of the previous upgrades did not work out 100% correct this may bite you now. The following commands can be run in the rails console to look for 'bad' data. - -All project owners should have an owner: - -``` -Project.all.select { |project| project.owner.blank? } -``` - -Every user should have a namespace: - -``` -User.all.select { |u| u.namespace.blank? } -``` - -Projects in the global namespace should not conflict with projects in the owner namespace: - -``` -Project.where(namespace_id: nil).select { |p| Project.where(path: p.path, namespace_id: p.owner.try(:namespace).try(:id)).present? } -``` diff --git a/doc/update/6.0-to-6.1.md b/doc/update/6.0-to-6.1.md deleted file mode 100644 index c5eba1c01c457e341e28ef8b9508b082123d48f8..0000000000000000000000000000000000000000 --- a/doc/update/6.0-to-6.1.md +++ /dev/null @@ -1,108 +0,0 @@ -# From 6.0 to 6.1 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.0-to-6.1.md) for the most up to date instructions.* - -## Warning - -GitLab 6.1 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. - -**In 6.1 we remove a lot of deprecated code.** - -**You should update to 6.0 before installing 6.1 so all the necessary conversions are run.** - -## Deprecations - -### Global issue numbers - -In 6.1 issue numbers are project specific. This means all issues are renumbered and get a new number in their URL. If you use an old issue number URL and the issue number does not exist yet you are redirected to the new one. This conversion does not trigger if the old number already exists for this project, this is unlikely but will happen with old issues and large projects. - -## 0. Backup - -It's useful to make a backup just in case things go south (with MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version): - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -sudo -u git -H git checkout 6-1-stable -# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-1-stable-ee -``` - -## 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.7.9 -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -#PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production -``` - -## 5. Update config files - -- Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-1-stable/config/gitlab.yml.example but with your settings. -- Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-1-stable/config/unicorn.rb.example but with your settings. - -## 6. Update Init script - -```bash -sudo rm /etc/init.d/gitlab -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -## 7. Start application - - sudo service gitlab start - sudo service nginx restart - -## 8. Check application status - -Check if GitLab and its environment are configured correctly: - - cd /home/git/gitlab - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (6.0) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 5.4 to 6.0](5.4-to-6.0.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/6.1-to-6.2.md b/doc/update/6.1-to-6.2.md deleted file mode 100644 index a534528108a9171c1087159b5094be963659a1d4..0000000000000000000000000000000000000000 --- a/doc/update/6.1-to-6.2.md +++ /dev/null @@ -1,122 +0,0 @@ -# From 6.1 to 6.2 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.1-to-6.2.md) for the most up to date instructions.* - -**You should update to 6.1 before installing 6.2 so all the necessary conversions are run.** - -## 0. Backup - -It's useful to make a backup just in case things go south: (With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version). - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -sudo -u git -H git checkout 6-2-stable # Latest version of 6-2-stable addresses CVE-2013-4489 -# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-2-stable-ee -``` - -## 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.7.9 # Addresses multiple critical security vulnerabilities -``` - -## 4. Install additional packages - -```bash -# Add support for logrotate for better log file handling -sudo apt-get install logrotate -``` - -## 5. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -#PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production -``` - -## 6. Update config files - -TIP: to see what changed in `gitlab.yml.example` in this release use next command: - -``` -git diff 6-1-stable:config/gitlab.yml.example 6-2-stable:config/gitlab.yml.example -``` - -- Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-2-stable/config/gitlab.yml.example but with your settings. - -- Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-2-stable/config/unicorn.rb.example but with your settings. - -- Copy rack attack middleware config: - - ```bash - sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb - ``` - -- Uncomment `config.middleware.use Rack::Attack` in `/home/git/gitlab/config/application.rb` - -- Set up logrotate. - -```bash -sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab -``` - -## 7. Update Init script - -```bash -sudo rm /etc/init.d/gitlab -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -## 8. Start application - - sudo service gitlab start - sudo service nginx restart - -## 9. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (6.1) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 6.0 to 6.1](6.0-to-6.1.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/6.2-to-6.3.md b/doc/update/6.2-to-6.3.md deleted file mode 100644 index b08ebde08084bbe584c87c4527c278bf50e93ca9..0000000000000000000000000000000000000000 --- a/doc/update/6.2-to-6.3.md +++ /dev/null @@ -1,108 +0,0 @@ -# From 6.2 to 6.3 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.2-to-6.3.md) for the most up to date instructions.* - -**Requires version: 6.1 or 6.2.** - -## 0. Backup - -It's useful to make a backup just in case things go south: (With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -sudo -u git -H git checkout 6-3-stable -# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-3-stable-ee -``` - -## 3. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.7.9 # Addresses multiple critical security vulnerabilities -``` - -The gitlab-shell config changed recently, so check for config file changes and make `/home/git/gitlab-shell/config.yml` the same as - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production -``` - -## 5. Update config files - -TIP: to see what changed in gitlab.yml.example in this release use next command: - -``` -git diff 6-2-stable:config/gitlab.yml.example 6-3-stable:config/gitlab.yml.example -``` - -- Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-3-stable/config/gitlab.yml.example but with your settings. -- Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-3-stable/config/unicorn.rb.example but with your settings. - -```bash -# Copy rack attack middleware config -cd /home/git/gitlab -sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb -``` - -## 6. Update Init script - -```bash -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -## 7. Start application - - sudo service gitlab start - sudo service nginx restart - -## 8. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (6.2) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 6.1 to 6.2](6.1-to-6.2.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/6.3-to-6.4.md b/doc/update/6.3-to-6.4.md deleted file mode 100644 index 951d92dfeb54ec0ad9214e05ad41d225e3b23838..0000000000000000000000000000000000000000 --- a/doc/update/6.3-to-6.4.md +++ /dev/null @@ -1,90 +0,0 @@ -# From 6.3 to 6.4 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.3-to-6.4.md) for the most up to date instructions.* - -## 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - -```bash -sudo service gitlab stop -```` - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -sudo -u git -H git checkout 6-4-stable -# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-4-stable-ee -``` - -## 3. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.8.0 -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -## 5. Start application - -```bash -sudo service gitlab start -sudo service nginx restart -``` - -## 6. Check application status - -Check if GitLab and its environment are configured correctly: - -```bash -sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production -``` - -To make sure you didn't miss anything run a more thorough check with: - -```bash -sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production -``` - -If all items are green, then congratulations upgrade complete! - -## Things went south? Revert to previous version (6.3) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 6.2 to 6.3](6.2-to-6.3.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` diff --git a/doc/update/6.4-to-6.5.md b/doc/update/6.4-to-6.5.md deleted file mode 100644 index 0dae9a9fe594788679a21f5bb8ef30daf955b28e..0000000000000000000000000000000000000000 --- a/doc/update/6.4-to-6.5.md +++ /dev/null @@ -1,96 +0,0 @@ -# From 6.4 to 6.5 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.4-to-6.5.md) for the most up to date instructions.* - -## 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 6-5-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 6-5-stable-ee -``` - -## 3. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.8.0 -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -## 5. Start application - - sudo service gitlab start - sudo service nginx restart - -## 6. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (6.4) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 6.3 to 6.4](6.3-to-6.4.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` - -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/6.5-to-6.6.md b/doc/update/6.5-to-6.6.md deleted file mode 100644 index c24e83eb006562fb4257bc931d516ee1e3797347..0000000000000000000000000000000000000000 --- a/doc/update/6.5-to-6.6.md +++ /dev/null @@ -1,97 +0,0 @@ -# From 6.5 to 6.6 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.5-to-6.6.md) for the most up to date instructions.* - -## 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 6-6-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 6-6-stable-ee -``` - -## 3. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.8.0 -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -## 5. Start application - - sudo service gitlab start - sudo service nginx restart - -## 6. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (6.5) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 6.4 to 6.5](6.4-to-6.5.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` - -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/6.6-to-6.7.md b/doc/update/6.6-to-6.7.md deleted file mode 100644 index b4298c93429b2d28e34e5ac74ad278edf3e90065..0000000000000000000000000000000000000000 --- a/doc/update/6.6-to-6.7.md +++ /dev/null @@ -1,109 +0,0 @@ -# From 6.6 to 6.7 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.6-to-6.7.md) for the most up to date instructions.* - -## 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - - sudo service gitlab stop - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 6-7-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 6-7-stable-ee -``` - -## 3. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.9.1 -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab - -# Update the logrotate configuration (keep logs for 90 days instead of 52 weeks) -sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab - -# Compress existing .log.1 files because we turned off delaycompress in logrotate -sudo -u git -H gzip /home/git/gitlab/log/*.log.1 -sudo -u git -H gzip /home/git/gitlab-shell/gitlab-shell.log.1 - -# Close access to gitlab-satellites for others -sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites - -# Add directory for uploads -sudo -u git -H mkdir -p /home/git/gitlab/public/uploads -``` - -## 5. Start application - - sudo service gitlab start - sudo service nginx restart - -## 6. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (6.6) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 6.5 to 6.6](6.5-to-6.6.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` - -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/6.7-to-6.8.md b/doc/update/6.7-to-6.8.md deleted file mode 100644 index 4fb90639f1690f6afe73240f7483c72859ed7487..0000000000000000000000000000000000000000 --- a/doc/update/6.7-to-6.8.md +++ /dev/null @@ -1,122 +0,0 @@ -# From 6.7 to 6.8 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.7-to-6.8.md) for the most up to date instructions.* - -## 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -## 1. Stop server - -```bash -sudo service gitlab stop -``` - -## 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 6-8-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 6-8-stable-ee -``` - -## 3. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.9.3 -``` - -## 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab - -# Close access to gitlab-satellites for others -sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites -``` - -## 5. Update config files - -### New configuration options for gitlab.yml - -There are new configuration options available for gitlab.yml. View them with the command below and apply them to your current gitlab.yml if desired. - -``` -git diff 6-7-stable:config/gitlab.yml.example 6-8-stable:config/gitlab.yml.example -``` - -### MySQL? Remove reaping frequency - -If you are using MySQL as a database, remove `reaping_frequency` from you database.yml to prevent crashes. [Relevant commit](https://gitlab.com/gitlab-org/gitlab-ce/commit/5163a8fcb9cfd63435560fda00173b76df2ccc93). - -### HTTPS? Disable gzip - -If you are using HTTPS, disable gzip as in [this commit](https://gitlab.com/gitlab-org/gitlab-ce/commit/563fec734912d81cd7caea6fa8ec2b397fb72a9b) to prevent BREACH attacks. - -### Turn on asset compression - -To improve performance, enable gzip asset compression as seen [in this commit](https://gitlab.com/gitlab-org/gitlab-ce/commit/8af94ed75505f0253823b9b2d44320fecea5b5fb). - -## 6. Start application - - sudo service gitlab start - sudo service nginx restart - -## 7. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (6.7) - -### 1. Revert the code to the previous version - -Follow the [upgrade guide from 6.6 to 6.7](6.6-to-6.7.md), except for the database migration (the backup is already migrated to the previous version). - -### 2. Restore from the backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/6.8-to-6.9.md b/doc/update/6.8-to-6.9.md deleted file mode 100644 index b9b8b63f652fdc47a83f7aeb5def5a0aab418cea..0000000000000000000000000000000000000000 --- a/doc/update/6.8-to-6.9.md +++ /dev/null @@ -1,103 +0,0 @@ -# From 6.8 to 6.9 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.8-to-6.9.md) for the most up to date instructions.* - -### 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 1. Stop server - -```bash -sudo service gitlab stop -``` - -### 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 6-9-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 6-9-stable-ee -``` - -### 3. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.9.4 -``` - -### 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production -``` - -### 5. Update config files - -#### New configuration options for gitlab.yml - -There are new configuration options available for gitlab.yml. View them with the command below and apply them to your current gitlab.yml if desired. - -``` -git diff 6-8-stable:config/gitlab.yml.example 6-9-stable:config/gitlab.yml.example -``` - -### 6. Start application - - sudo service gitlab start - sudo service nginx restart - -### 7. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (6.8) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 6.7 to 6.8](6.7-to-6.8.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/6.9-to-7.0.md b/doc/update/6.9-to-7.0.md deleted file mode 100644 index 236430b5951618062a534e88e9a20ce9dfd2e5cc..0000000000000000000000000000000000000000 --- a/doc/update/6.9-to-7.0.md +++ /dev/null @@ -1,141 +0,0 @@ -# From 6.9 to 7.0 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.9-to-7.0.md) for the most up to date instructions.* - -### 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 1. Stop server - -```bash -sudo service gitlab stop -``` - -### 2. Update Ruby - -If you are still using Ruby 1.9.3 or below, you will need to update Ruby. -You can check which version you are running with `ruby -v`. - -If you are you running Ruby 2.0.x, you do not need to upgrade ruby, but can consider doing so for performance reasons. - -If you are running Ruby 2.1.1 consider upgrading to 2.1.2, because of the high memory usage of Ruby 2.1.1. - -Install, update dependencies: - -```bash -sudo apt-get install build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev curl -``` - -Download and compile Ruby: - -```bash -mkdir /tmp/ruby && cd /tmp/ruby -curl -L --progress ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz | tar xz -cd ruby-2.1.2 -./configure --disable-install-rdoc -make -sudo make install -``` - -Install Bundler: - -```bash -sudo gem install bundler --no-ri --no-rdoc -``` - -### 3. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-0-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-0-stable-ee -``` - -### 4. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.9.6 -``` - -### 5. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 6. Update config files - -#### New configuration options for gitlab.yml - -There are new configuration options available for gitlab.yml. View them with the command below and apply them to your current gitlab.yml if desired. - -``` -git diff origin/6-9-stable:config/gitlab.yml.example origin/7-0-stable:config/gitlab.yml.example -``` - -* HTTP setups: Make `/etc/nginx/sites-available/nginx` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-0-stable/lib/support/nginx/gitlab but with your settings. -* HTTPS setups: Make `/etc/nginx/sites-available/nginx-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-0-stable/lib/support/nginx/gitlab-ssl but with your setting - -### 7. Start application - - sudo service gitlab start - sudo service nginx restart - -### 8. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (6.9) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 6.8 to 6.9](6.8-to-6.9.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/7.0-to-7.1.md b/doc/update/7.0-to-7.1.md deleted file mode 100644 index a4e9be9946e07fdcbc7f1e7f9416607862a45236..0000000000000000000000000000000000000000 --- a/doc/update/7.0-to-7.1.md +++ /dev/null @@ -1,138 +0,0 @@ -# From 7.0 to 7.1 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/7.0-to-7.1.md) for the most up to date instructions.* - -### 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 1. Stop server - -```bash -sudo service gitlab stop -``` - -### 2. Update Ruby - -If you are still using Ruby 1.9.3 or below, you will need to update Ruby. -You can check which version you are running with `ruby -v`. - -If you are you running Ruby 2.0.x, you do not need to upgrade ruby, but can consider doing so for performance reasons. - -If you are running Ruby 2.1.1 consider upgrading to 2.1.2, because of the high memory usage of Ruby 2.1.1. - -Install, update dependencies: - -```bash -sudo apt-get install build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev curl -``` - -Download and compile Ruby: - -```bash -mkdir /tmp/ruby && cd /tmp/ruby -curl -L --progress ftp://ftp.ruby-lang.org/pub/ruby/2.1/ruby-2.1.2.tar.gz | tar xz -cd ruby-2.1.2 -./configure --disable-install-rdoc -make -sudo make install -``` - -Install Bundler: - -```bash -sudo gem install bundler --no-ri --no-rdoc -``` - -### 3. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-1-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-1-stable-ee -``` - -### 4. Update gitlab-shell (and its config) - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.9.6 -``` - -### 5. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 6. Update config files - -#### New configuration options for gitlab.yml - -There are new configuration options available for gitlab.yml. View them with the command below and apply them to your current gitlab.yml if desired. - -``` -git diff 7-0-stable:config/gitlab.yml.example 7-1-stable:config/gitlab.yml.example -``` - -### 7. Start application - - sudo service gitlab start - sudo service nginx restart - -### 8. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (7.0) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 6.9 to 7.0](6.9-to-7.0.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/7.1-to-7.2.md b/doc/update/7.1-to-7.2.md deleted file mode 100644 index 88cb63d7d411a51ffb8c717a51142c2a9086bbbb..0000000000000000000000000000000000000000 --- a/doc/update/7.1-to-7.2.md +++ /dev/null @@ -1,137 +0,0 @@ -# From 7.1 to 7.2 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/7.1-to-7.2.md) for the most up to date instructions.* - -## Editable labels - -In GitLab 7.2 we replace Issue and Merge Request tags with labels, making it -possible to edit the label text and color. The characters `?`, `&` and `,` are -no longer allowed however so those will be removed from your tags during the -database migrations for GitLab 7.2. - -### 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 1. Stop server - -```bash -sudo service gitlab stop -``` - -### 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-2-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-2-stable-ee -``` - -### 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v1.9.8 -``` - -### 4. Install new system dependencies - -The latest version of the 'rugged' gem requires `pkg-config` and `cmake` to -build its native extensions. - -```bash -sudo apt-get install pkg-config cmake -``` - -### 5. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 6. Update config files - -#### New configuration options for `gitlab.yml` - -There are new configuration options available for `gitlab.yml`. View them with the command below and apply them to your current `gitlab.yml`. - -``` -git diff 7-1-stable:config/gitlab.yml.example 7-2-stable:config/gitlab.yml.example -``` - -* HTTP setups: Make `/etc/nginx/sites-available/nginx` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-0-stable/lib/support/nginx/gitlab but with your settings. -* HTTPS setups: Make `/etc/nginx/sites-available/nginx-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-0-stable/lib/support/nginx/gitlab-ssl but with your setting - -Update rack attack middleware config - -``` -sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb -``` - -### 7. Start application - - sudo service gitlab start - sudo service nginx restart - -### 8. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -### 9. Update OmniAuth configuration - -When using Google omniauth login, changes of the Google account required. -Ensure that `Contacts API` and the `Google+ API` are enabled in the [Google Developers Console](https://console.developers.google.com/). -More details can be found at the [integration documentation](../integration/google.md). - -## Things went south? Revert to previous version (7.1) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 7.0 to 7.1](7.0-to-7.1.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/7.2-to-7.3.md b/doc/update/7.2-to-7.3.md deleted file mode 100644 index 18f77d6396e378864b1cff46a6ead73c6ac585fd..0000000000000000000000000000000000000000 --- a/doc/update/7.2-to-7.3.md +++ /dev/null @@ -1,145 +0,0 @@ -# From 7.2 to 7.3 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/7.2-to-7.3.md) for the most up to date instructions.* - -### 0. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 1. Stop server - -```bash -sudo service gitlab stop -``` - -### 2. Get latest code - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-3-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-3-stable-ee -``` - -### 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v2.0.1 -``` - -### 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - - -### 5. Configure Redis to use sockets - - # Configure redis to use sockets - sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.orig - # Disable Redis listening on TCP by setting 'port' to 0 - sed 's/^port .*/port 0/' /etc/redis/redis.conf.orig | sudo tee /etc/redis/redis.conf - # Enable Redis socket for default Debian / Ubuntu path - echo 'unixsocket /var/run/redis/redis.sock' | sudo tee -a /etc/redis/redis.conf - # Be sure redis group can write to the socket, enable only if supported (>= redis 2.4.0). - sudo sed -i '/# unixsocketperm/ s/^# unixsocketperm.*/unixsocketperm 0775/' /etc/redis/redis.conf - # Activate the changes to redis.conf - sudo service redis-server restart - # Add git to the redis group - sudo usermod -aG redis git - - # Configure Redis connection settings - sudo -u git -H cp config/resque.yml.example config/resque.yml - # Change the Redis socket path if you are not using the default Debian / Ubuntu configuration - sudo -u git -H editor config/resque.yml - - # Configure gitlab-shell to use Redis sockets - sudo -u git -H sed -i 's|^ # socket.*| socket: /var/run/redis/redis.sock|' /home/git/gitlab-shell/config.yml - -### 6. Update config files - -#### New configuration options for gitlab.yml - -There are new configuration options available for gitlab.yml. View them with the command below and apply them to your current gitlab.yml. - -``` -git diff origin/7-2-stable:config/gitlab.yml.example origin/7-3-stable:config/gitlab.yml.example -``` - -``` -# Use the default Unicorn socket backlog value of 1024 -sudo -u git -H sed -i 's/:backlog => 64/:backlog => 1024/' config/unicorn.rb -``` - -* HTTP setups: Make `/etc/nginx/sites-available/nginx` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-3-stable/lib/support/nginx/gitlab but with your settings. -* HTTPS setups: Make `/etc/nginx/sites-available/nginx-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-3-stable/lib/support/nginx/gitlab-ssl but with your setting - -### 7. Start application - - sudo service gitlab start - sudo service nginx restart - -### 8. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -### 9. Update OmniAuth configuration - -When using Google omniauth login, changes of the Google account required. -Ensure that `Contacts API` and the `Google+ API` are enabled in the [Google Developers Console](https://console.developers.google.com/). -More details can be found at the [integration documentation](../integration/google.md). - -## Things went south? Revert to previous version (7.2) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 7.1 to 7.2](7.1-to-7.2.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/7.3-to-7.4.md b/doc/update/7.3-to-7.4.md deleted file mode 100644 index 53e739c06fba6e902d17aa2e07bae5e39ef2c8ce..0000000000000000000000000000000000000000 --- a/doc/update/7.3-to-7.4.md +++ /dev/null @@ -1,197 +0,0 @@ -# From 7.3 to 7.4 -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/7.3-to-7.4.md) for the most up to date instructions.* - -### 0. Stop server - - sudo service gitlab stop - -### 1. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 2. Get latest code - -```bash -sudo -u git -H git fetch --all -sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-4-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-4-stable-ee -``` - -### 3. Install libs, migrations, etc. - -```bash -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 4. Update config files - -#### New configuration options for gitlab.yml - -There are new configuration options available for gitlab.yml. View them with the command below and apply them to your current gitlab.yml. - -``` -git diff origin/7-3-stable:config/gitlab.yml.example origin/7-4-stable:config/gitlab.yml.example -``` - -#### Change timeout for unicorn - -``` -# set timeout to 60 -sudo -u git -H editor config/unicorn.rb -``` - -#### Change Nginx HTTPS settings - -* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-4-stable/lib/support/nginx/gitlab-ssl but with your setting - -#### MySQL Databases: Update database.yml config file - -* Add `collation: utf8_general_ci` to `config/database.yml` as seen in [config/database.yml.mysql](/config/database.yml.mysql) - -``` -sudo -u git -H editor config/database.yml -``` - -### 5. Start application - - sudo service gitlab start - sudo service nginx restart - -### 6. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - - -### 7. Optional optimizations for GitLab setups with MySQL databases - -Only applies if running MySQL database created with GitLab 6.7 or earlier. If you are not experiencing any issues you may not need the following instructions however following them will bring your database in line with the latest recommended installation configuration and help avoid future issues. Be sure to follow these directions exactly. These directions should be safe for any MySQL instance but to be sure make a current MySQL database backup beforehand. - -``` -# Stop GitLab -sudo service gitlab stop - -# Secure your MySQL installation (added in GitLab 6.2) -sudo mysql_secure_installation - -# Login to MySQL -mysql -u root -p - -# do not type the 'mysql>', this is part of the prompt - -# Convert all tables to use the InnoDB storage engine (added in GitLab 6.8) -SELECT CONCAT('ALTER TABLE gitlabhq_production.', table_name, ' ENGINE=InnoDB;') AS 'Copy & run these SQL statements:' FROM information_schema.tables WHERE table_schema = 'gitlabhq_production' AND `ENGINE` <> 'InnoDB' AND `TABLE_TYPE` = 'BASE TABLE'; - -# If previous query returned results, copy & run all shown SQL statements - -# Convert all tables to correct character set -SET foreign_key_checks = 0; -SELECT CONCAT('ALTER TABLE gitlabhq_production.', table_name, ' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') AS 'Copy & run these SQL statements:' FROM information_schema.tables WHERE table_schema = 'gitlabhq_production' AND `TABLE_COLLATION` <> 'utf8_unicode_ci' AND `TABLE_TYPE` = 'BASE TABLE'; - -# If previous query returned results, copy & run all shown SQL statements - -# turn foreign key checks back on -SET foreign_key_checks = 1; - -# Find MySQL users -mysql> SELECT user FROM mysql.user WHERE user LIKE '%git%'; - -# If git user exists and gitlab user does not exist -# you are done with the database cleanup tasks -mysql> \q - -# If both users exist skip to Delete gitlab user - -# Create new user for GitLab (changed in GitLab 6.4) -# change $password in the command below to a real password you pick -mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY '$password'; - -# Grant the git user necessary permissions on the database -mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES ON `gitlabhq_production`.* TO 'git'@'localhost'; - -# Delete the old gitlab user -mysql> DELETE FROM mysql.user WHERE user='gitlab'; - -# Quit the database session -mysql> \q - -# Try connecting to the new database with the new user -sudo -u git -H mysql -u git -p -D gitlabhq_production - -# Type the password you replaced $password with earlier - -# You should now see a 'mysql>' prompt - -# Quit the database session -mysql> \q - -# Update database configuration details -# See config/database.yml.mysql for latest recommended configuration details -# Remove the reaping_frequency setting line if it exists (removed in GitLab 6.8) -# Set production -> pool: 10 (updated in GitLab 5.3) -# Set production -> username: git -# Set production -> password: the password your replaced $password with earlier -sudo -u git -H editor /home/git/gitlab/config/database.yml - -# Start GitLab -sudo service gitlab start -sudo service nginx restart - -# Run thorough check -sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production -``` - - -## Things went south? Revert to previous version (7.3) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 7.2 to 7.3](7.2-to-7.3.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. - - - - diff --git a/doc/update/7.4-to-7.5.md b/doc/update/7.4-to-7.5.md deleted file mode 100644 index 673eab3c56ec21e025171df98f50aa850a5ffe64..0000000000000000000000000000000000000000 --- a/doc/update/7.4-to-7.5.md +++ /dev/null @@ -1,108 +0,0 @@ -# From 7.4 to 7.5 - -### 0. Stop server - - sudo service gitlab stop - -### 1. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 2. Get latest code - -```bash -sudo -u git -H git fetch --all -sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-5-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-5-stable-ee -``` - -### 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v2.2.0 -``` - -### 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 5. Update config files - -#### New configuration options for gitlab.yml - -There are new configuration options available for gitlab.yml. View them with the command below and apply them to your current gitlab.yml. - -``` -git diff origin/7-4-stable:config/gitlab.yml.example origin/7-5-stable:config/gitlab.yml.example -``` - -#### Change Nginx settings - -* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`](/lib/support/nginx/gitlab) but with your settings -* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`](/lib/support/nginx/gitlab-ssl) but with your setting - -### 6. Start application - - sudo service gitlab start - sudo service nginx restart - -### 7. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (7.4) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 7.3 to 7.4](7.3-to-7.4.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/7.5-to-7.6.md b/doc/update/7.5-to-7.6.md deleted file mode 100644 index 35cd437fdc44dfadbbbd7e553e68e121fdebd8df..0000000000000000000000000000000000000000 --- a/doc/update/7.5-to-7.6.md +++ /dev/null @@ -1,114 +0,0 @@ -# From 7.5 to 7.6 - -### 0. Stop server - - sudo service gitlab stop - -### 1. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 2. Get latest code - -```bash -sudo -u git -H git fetch --all -sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-6-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-6-stable-ee -``` - -### 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v2.4.0 -``` - -### 4. Install libs, migrations, etc. - -```bash -sudo apt-get install libkrb5-dev - -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 5. Update config files - -#### New configuration options for `gitlab.yml` - -There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them to your current `gitlab.yml`. - -``` -git diff origin/7-5-stable:config/gitlab.yml.example origin/7-6-stable:config/gitlab.yml.example -``` - -#### Change Nginx settings - -* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`](/lib/support/nginx/gitlab) but with your settings -* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`](/lib/support/nginx/gitlab-ssl) but with your setting - -#### Setup time zone (optional) - -Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`](config/application.rb) (unlikely), unset it. - -### 6. Start application - - sudo service gitlab start - sudo service nginx restart - -### 7. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## Things went south? Revert to previous version (7.5) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 7.4 to 7.5](7.4-to-7.5.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/7.6-to-7.7.md b/doc/update/7.6-to-7.7.md deleted file mode 100644 index 59243713156c21d828363941282ed339ca762ce9..0000000000000000000000000000000000000000 --- a/doc/update/7.6-to-7.7.md +++ /dev/null @@ -1,119 +0,0 @@ -# From 7.6 to 7.7 - -### 0. Stop server - - sudo service gitlab stop - -### 1. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 2. Get latest code - -```bash -sudo -u git -H git fetch --all -sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-7-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-7-stable-ee -``` - -### 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v2.4.2 -``` - -### 4. Install libs, migrations, etc. - -```bash -sudo apt-get install libkrb5-dev - -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 5. Update config files - -#### New configuration options for `gitlab.yml` - -There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them to your current `gitlab.yml`. - -``` -git diff origin/7-6-stable:config/gitlab.yml.example origin/7-7-stable:config/gitlab.yml.example -``` - -#### Change Nginx settings - -* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`](/lib/support/nginx/gitlab) but with your settings -* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`](/lib/support/nginx/gitlab-ssl) but with your setting - -#### Setup time zone (optional) - -Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`](config/application.rb) (unlikely), unset it. - -### 6. Start application - - sudo service gitlab start - sudo service nginx restart - -### 7. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -### 8. GitHub settings (if applicable) - -If you are using GitHub as an OAuth provider for authentication, you should change the callback URL so that it -only contains a root URL (ex. `https://gitlab.example.com/`) - -## Things went south? Revert to previous version (7.6) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 7.5 to 7.6](7.5-to-7.6.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/7.7-to-7.8.md b/doc/update/7.7-to-7.8.md deleted file mode 100644 index 46ca163c1bbda22adce732130f2797c5ca1c53fc..0000000000000000000000000000000000000000 --- a/doc/update/7.7-to-7.8.md +++ /dev/null @@ -1,120 +0,0 @@ -# From 7.7 to 7.8 - -### 0. Stop server - - sudo service gitlab stop - -### 1. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 2. Get latest code - -```bash -sudo -u git -H git fetch --all -sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-8-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-8-stable-ee -``` - -### 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v2.5.4 -``` - -### 4. Install libs, migrations, etc. - -```bash -sudo apt-get install libkrb5-dev - -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 5. Update config files - -#### New configuration options for `gitlab.yml` - -There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them to your current `gitlab.yml`. - -``` -git diff origin/7-7-stable:config/gitlab.yml.example origin/7-8-stable:config/gitlab.yml.example -``` - -#### Change Nginx settings - -* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`](/lib/support/nginx/gitlab) but with your settings. -* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`](/lib/support/nginx/gitlab-ssl) but with your settings. -* A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section. - -#### Setup time zone (optional) - -Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`](config/application.rb) (unlikely), unset it. - -### 6. Start application - - sudo service gitlab start - sudo service nginx restart - -### 7. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -### 8. GitHub settings (if applicable) - -If you are using GitHub as an OAuth provider for authentication, you should change the callback URL so that it -only contains a root URL (ex. `https://gitlab.example.com/`) - -## Things went south? Revert to previous version (7.7) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 7.6 to 7.7](7.6-to-7.7.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/7.8-to-7.9.md b/doc/update/7.8-to-7.9.md deleted file mode 100644 index 28fd433e1c8272246a06fdd800194d9e67852b69..0000000000000000000000000000000000000000 --- a/doc/update/7.8-to-7.9.md +++ /dev/null @@ -1,120 +0,0 @@ -# From 7.8 to 7.9 - -### 0. Stop server - - sudo service gitlab stop - -### 1. Backup - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 2. Get latest code - -```bash -sudo -u git -H git fetch --all -sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically -``` - -For GitLab Community Edition: - -```bash -sudo -u git -H git checkout 7-9-stable -``` - -OR - -For GitLab Enterprise Edition: - -```bash -sudo -u git -H git checkout 7-9-stable-ee -``` - -### 3. Update gitlab-shell - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v2.6.0 -``` - -### 4. Install libs, migrations, etc. - -```bash -sudo apt-get install nodejs - -cd /home/git/gitlab - -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment - -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -# Run database migrations -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production - -# Clean up assets and cache -sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production - -# Update init.d script -sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab -``` - -### 5. Update config files - -#### New configuration options for `gitlab.yml` - -There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them to your current `gitlab.yml`. - -``` -git diff origin/7-8-stable:config/gitlab.yml.example origin/7-9-stable:config/gitlab.yml.example -``` - -#### Change Nginx settings - -* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`](/lib/support/nginx/gitlab) but with your settings. -* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`](/lib/support/nginx/gitlab-ssl) but with your settings. -* A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section. - -#### Setup time zone (optional) - -Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`](config/application.rb) (unlikely), unset it. - -### 6. Start application - - sudo service gitlab start - sudo service nginx restart - -### 7. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -### 8. GitHub settings (if applicable) - -If you are using GitHub as an OAuth provider for authentication, you should change the callback URL so that it -only contains a root URL (ex. `https://gitlab.example.com/`) - -## Things went south? Revert to previous version (7.8) - -### 1. Revert the code to the previous version -Follow the [upgrade guide from 7.7 to 7.8](7.7-to-7.8.md), except for the database migration -(The backup is already migrated to the previous version) - -### 2. Restore from the backup: - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production -``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/README.md b/doc/update/README.md deleted file mode 100644 index 0472537eeb5ff9532cece6381f30b9e451363bb0..0000000000000000000000000000000000000000 --- a/doc/update/README.md +++ /dev/null @@ -1,16 +0,0 @@ -Depending on the installation method and your GitLab version, there are multiple update guides. Choose one that fits your needs. - -## Omnibus Packages - -- [Omnibus update guide](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md) contains the steps needed to update a GitLab [package](https://about.gitlab.com/downloads/). - -## Installation from source - -- [The individual upgrade guides](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update) are for those who have installed GitLab from source. -- [The CE to EE update guides](https://gitlab.com/subscribers/gitlab-ee/tree/master/doc/update) are for subscribers of the Enterprise Edition only. The steps are very similar to a version upgrade: stop the server, get the code, update config files for the new functionality, install libs and do migrations, update the init script, start the application and check the application status. -- [Upgrader](upgrader.md) is an automatic ruby script that performs the update for installations from source. -- [Patch versions](patch_versions.md) guide includes the steps needed for a patch version, eg. 6.2.0 to 6.2.1. - -## Miscellaneous - -- [MySQL to PostgreSQL](mysql_to_postgresql.md) guides you through migrating your database from MySQL to PostgreSQL. diff --git a/doc/update/mysql_to_postgresql.md b/doc/update/mysql_to_postgresql.md deleted file mode 100644 index 50941db25f6ef494c4ef2624dea2086c1ba9399e..0000000000000000000000000000000000000000 --- a/doc/update/mysql_to_postgresql.md +++ /dev/null @@ -1,116 +0,0 @@ -# Migrating GitLab from MySQL to Postgres -*Make sure you view this [guide from the `master` branch](../../../master/doc/update/mysql_to_postgresql.md) for the most up to date instructions.* - -If you are replacing MySQL with Postgres while keeping GitLab on the same server all you need to do is to export from MySQL, import into Postgres and rebuild the indexes as described below. If you are also moving GitLab to another server, or if you are switching to omnibus-gitlab, you may want to use a GitLab backup file. The second part of this documents explains the procedure to do this. - -## Export from MySQL and import into Postgres - -Use this if you are keeping GitLab on the same server. - -``` -sudo service gitlab stop - -# Update /home/git/gitlab/config/database.yml - -git clone https://github.com/gitlabhq/mysql-postgresql-converter.git -b gitlab -cd mysql-postgresql-converter -mysqldump --compatible=postgresql --default-character-set=utf8 -r databasename.mysql -u root gitlabhq_production -p -python db_converter.py databasename.mysql databasename.psql - -# Import the database dump as the application database user -sudo -u git psql -f databasename.psql -d gitlabhq_production - -# Rebuild indexes (see below) - -# Install gems for PostgreSQL (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment - -sudo service gitlab start -``` - -## Rebuild indexes - -The lanyrd database converter script does not preserve all indexes, so we have to recreate them ourselves after migrating from MySQL. It is not necessary to shut down GitLab for this process. - -### For non-omnibus installations - -On non-omnibus installations (distributed using Git) we retrieve the index declarations from version control using `git stash`. - -``` -# Clone the database converter on your Postgres-backed GitLab server -cd /tmp -git clone https://github.com/gitlabhq/mysql-postgresql-converter.git -b gitlab - -cd /home/git/gitlab - -# Stash changes to db/schema.rb to make sure we can find the right index statements -sudo -u git -H git stash - -# Generate add_index.rb -ruby /tmp/mysql-postgresql-converter/add_index_statements.rb db/schema.rb > /tmp/mysql-postgresql-converter/add_index.rb - -# Create the indexes -sudo -u git -H bundle exec rails runner -e production 'eval $stdin.read' < /tmp/mysql-postgresql-converter/add_index.rb -``` - -### For omnibus-gitlab installations - -On omnibus-gitlab we need to get the index declarations from a file called `schema.rb.bundled`. For versions older than 6.9, we need to download the file. - -``` -# Clone the database converter on your Postgres-backed GitLab server -cd /tmp -/opt/gitlab/embedded/bin/git clone https://github.com/gitlabhq/mysql-postgresql-converter.git -b gitlab -cd /tmp/mysql-postgresql-converter - -# Download schema.rb.bundled if necessary -test -e /opt/gitlab/embedded/service/gitlab-rails/db/schema.rb.bundled || sudo /opt/gitlab/embedded/bin/curl -o /opt/gitlab/embedded/service/gitlab-rails/db/schema.rb.bundled https://gitlab.com/gitlab-org/gitlab-ce/raw/v6.9.1/db/schema.rb - -# Generate add_index.rb -/opt/gitlab/embedded/bin/ruby add_index_statements.rb /opt/gitlab/embedded/service/gitlab-rails/db/schema.rb.bundled > add_index.rb - -# Create the indexes -/opt/gitlab/bin/gitlab-rails runner 'eval $stdin.read' < add_index.rb -``` - -## Converting a GitLab backup file from MySQL to Postgres -**Note:** Please make sure to have Python 2.7.x (or higher) installed. - -GitLab backup files (`_gitlab_backup.tar`) contain a SQL dump. Using the lanyrd database converter we can replace a MySQL database dump inside the tar file with a Postgres database dump. This can be useful if you are moving to another server. - -``` -# Stop GitLab -sudo service gitlab stop - -# Create the backup -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production - -# Note the filename of the backup that was created. We will call it -# TIMESTAMP_gitlab_backup.tar below. - -# Move the backup file we will convert to its own directory -sudo -u git -H mkdir -p tmp/backups/postgresql -sudo -u git -H mv tmp/backups/TIMESTAMP_gitlab_backup.tar tmp/backups/postgresql/ - -# Create a separate database dump with PostgreSQL compatibility -cd tmp/backups/postgresql -sudo -u git -H mysqldump --compatible=postgresql --default-character-set=utf8 -r gitlabhq_production.mysql -u root gitlabhq_production -p - -# Clone the database converter -sudo -u git -H git clone https://github.com/gitlabhq/mysql-postgresql-converter.git -b gitlab - -# Convert gitlabhq_production.mysql -sudo -u git -H mkdir db -sudo -u git -H python mysql-postgresql-converter/db_converter.py gitlabhq_production.mysql db/database.sql - -# Replace the MySQL dump in TIMESTAMP_gitlab_backup.tar. - -# Warning: if you forget to replace TIMESTAMP below, tar will create a new file -# 'TIMESTAMP_gitlab_backup.tar' without giving an error. - -sudo -u git -H tar rf TIMESTAMP_gitlab_backup.tar db/database.sql - -# Done! TIMESTAMP_gitlab_backup.tar can now be restored into a Postgres GitLab -# installation. Remember to recreate the indexes after the import. -``` diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md deleted file mode 100644 index e29ee2a7b3d295eb378fc3c2abc51a2a54047544..0000000000000000000000000000000000000000 --- a/doc/update/patch_versions.md +++ /dev/null @@ -1,70 +0,0 @@ -# Universal update guide for patch versions -*Make sure you view this [upgrade guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/patch_versions.md) from the `master` branch for the most up to date instructions.* - -For example from 6.2.0 to 6.2.1, also see the [semantic versioning specification](http://semver.org/). - -### 0. Backup - -It's useful to make a backup just in case things go south: -(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) - -```bash -cd /home/git/gitlab -sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production -``` - -### 1. Stop server - - sudo service gitlab stop - -### 2. Get latest code for the stable branch - -```bash -cd /home/git/gitlab -sudo -u git -H git fetch --all -sudo -u git -H git checkout LATEST_TAG -``` - -Replace LATEST_TAG with the latest GitLab tag you want to upgrade to, for example `v6.6.3`. - -### 3. Update gitlab-shell to the corresponding version - -```bash -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` -``` - -### 4. Install libs, migrations, etc. - -```bash -cd /home/git/gitlab - -#PostgreSQL -sudo -u git -H bundle install --without development test mysql --deployment - -# MySQL -sudo -u git -H bundle install --without development test postgres --deployment - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production -``` - -### 5. Start application - - sudo service gitlab start - sudo service nginx restart - -### 6. Check application status - -Check if GitLab and its environment are configured correctly: - - sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production - -To make sure you didn't miss anything run a more thorough check with: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade complete! diff --git a/doc/update/upgrader.md b/doc/update/upgrader.md deleted file mode 100644 index f62a53d3340c22a670b07e37b55fae2489190d64..0000000000000000000000000000000000000000 --- a/doc/update/upgrader.md +++ /dev/null @@ -1,76 +0,0 @@ -# GitLab Upgrader -*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/upgrader.md) for the most up to date instructions.* - -GitLab Upgrader - a ruby script that allows you easily upgrade GitLab to latest minor version. - -For example it can update your application from 6.4 to latest GitLab 6 version (like 6.6.1). - -You still need to create a backup and manually restart GitLab after running the script but all other operations are done by this upgrade script. - -If you have local changes to your GitLab repository the script will stash them and you need to use `git stash pop` after running the script. - -**GitLab Upgrader is available only for GitLab version 6.4.2 or higher.** - -**This script does NOT update gitlab-shell, it needs manual update. See step 5 below.** - -## 0. Backup - - cd /home/git/gitlab - sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production - -## 1. Stop server - - sudo service gitlab stop - -## 2. Run GitLab upgrade tool - -Note: GitLab 7.9 adds `nodejs` as a dependency. GitLab 7.6 adds `libkrb5-dev` as a dependency (installed by default on Ubuntu and OSX). GitLab 7.2 adds `pkg-config` and `cmake` as dependency. Please check the dependencies in the [installation guide.](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/installation.md#1-packages-dependencies) - - # Starting with GitLab version 7.0 upgrader script has been moved to bin directory - cd /home/git/gitlab - if [ -f bin/upgrade.rb ]; then sudo -u git -H ruby bin/upgrade.rb; else sudo -u git -H ruby script/upgrade.rb; fi - - # to perform a non-interactive install (no user input required) you can add -y - # if [ -f bin/upgrade.rb ]; then sudo -u git -H ruby bin/upgrade.rb -y; else sudo -u git -H ruby script/upgrade.rb -y; fi - -## 3. Start application - - sudo service gitlab start - sudo service nginx restart - -## 4. Check application status - -Check if GitLab and its dependencies are configured correctly: - - sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production - -If all items are green, then congratulations upgrade is complete! - -## 5. Upgrade GitLab Shell - -GitLab Shell might be outdated, running the commands below ensures you're using a compatible version: - -``` -cd /home/git/gitlab-shell -sudo -u git -H git fetch -sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` -``` - -## One line upgrade command - -You've read through the entire guide and probably already did all the steps one by one. - -Here is a one line command with step 1 to 5 for the next time you upgrade: - -```bash -cd /home/git/gitlab; \ - sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production; \ - sudo service gitlab stop; \ - if [ -f bin/upgrade.rb ]; then sudo -u git -H ruby bin/upgrade.rb -y; else sudo -u git -H ruby script/upgrade.rb -y; fi; \ - cd /home/git/gitlab-shell; \ - sudo -u git -H git fetch; \ - sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION`; \ - cd /home/git/gitlab; \ - sudo service gitlab start; \ - sudo service nginx restart; sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production -``` diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md deleted file mode 100644 index 851f50f5e9ad84061f67d28cced26bf3d28b247a..0000000000000000000000000000000000000000 --- a/doc/web_hooks/web_hooks.md +++ /dev/null @@ -1,218 +0,0 @@ -# Web hooks - -Project web hooks allow you to trigger an URL if new code is pushed or a new issue is created. - -You can configure web hooks to listen for specific events like pushes, issues or merge requests. GitLab will send a POST request with data to the web hook URL. - -Web hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. - -If you send a web hook to an SSL endpoint [the certificate will not be verified](https://gitlab.com/gitlab-org/gitlab-ce/blob/ccd617e58ea71c42b6b073e692447d0fe3c00be6/app/models/web_hook.rb#L35) since many people use self-signed certificates. - -## Push events - -Triggered when you push to the repository except when pushing tags. - -**Request body:** - -```json -{ - "object_kind": "push", - "before": "95790bf891e76fee5e1747ab589903a6a1f80f22", - "after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", - "ref": "refs/heads/master", - "user_id": 4, - "user_name": "John Smith", - "user_email": "john@example.com", - "project_id": 15, - "repository": { - "name": "Diaspora", - "url": "git@example.com:mike/diasporadiaspora.git", - "description": "", - "homepage": "http://example.com/mike/diaspora", - "git_http_url":"http://example.com/mike/diaspora.git", - "git_ssh_url":"git@example.com:mike/diaspora.git", - "visibility_level":0 - }, - "commits": [ - { - "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", - "message": "Update Catalan translation to e38cb41.", - "timestamp": "2011-12-12T14:27:31+02:00", - "url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327", - "author": { - "name": "Jordi Mallach", - "email": "jordi@softcatala.org" - } - }, - { - "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", - "message": "fixed readme", - "timestamp": "2012-01-03T23:36:29+02:00", - "url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", - "author": { - "name": "GitLab dev user", - "email": "gitlabdev@dv6700.(none)" - } - } - ], - "total_commits_count": 4 -} -``` - -## Tag events - -Triggered when you create (or delete) tags to the repository. - -**Request body:** - -```json -{ - "object_kind": "tag_push", - "ref": "refs/tags/v1.0.0", - "before": "0000000000000000000000000000000000000000", - "after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7", - "user_id": 1, - "user_name": "John Smith", - "project_id": 1, - "repository": { - "name": "jsmith", - "url": "ssh://git@example.com/jsmith/example.git", - "description": "", - "homepage": "http://example.com/jsmith/example", - "git_http_url":"http://example.com/jsmith/example.git", - "git_ssh_url":"git@example.com:jsmith/example.git", - "visibility_level":0 - }, - "commits": [], - "total_commits_count": 0 -} -``` - -## Issues events - -Triggered when a new issue is created or an existing issue was updated/closed/reopened. - -**Request body:** - -```json -{ - "object_kind": "issue", - "user": { - "name": "Administrator", - "username": "root", - "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" - }, - "object_attributes": { - "id": 301, - "title": "New API: create/update/delete file", - "assignee_id": 51, - "author_id": 51, - "project_id": 14, - "created_at": "2013-12-03T17:15:43Z", - "updated_at": "2013-12-03T17:15:43Z", - "position": 0, - "branch_name": null, - "description": "Create new API for manipulations with repository", - "milestone_id": null, - "state": "opened", - "iid": 23, - "url": "http://example.com/diaspora/issues/23", - "action": "open" - } -} -``` - -## Merge request events - -Triggered when a new merge request is created or an existing merge request was updated/merged/closed. - -**Request body:** - -```json -{ - "object_kind": "merge_request", - "user": { - "name": "Administrator", - "username": "root", - "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" - }, - "object_attributes": { - "id": 99, - "target_branch": "master", - "source_branch": "ms-viewport", - "source_project_id": 14, - "author_id": 51, - "assignee_id": 6, - "title": "MS-Viewport", - "created_at": "2013-12-03T17:23:34Z", - "updated_at": "2013-12-03T17:23:34Z", - "st_commits": null, - "st_diffs": null, - "milestone_id": null, - "state": "opened", - "merge_status": "unchecked", - "target_project_id": 14, - "iid": 1, - "description": "", - "source": { - "name": "awesome_project", - "ssh_url": "ssh://git@example.com/awesome_space/awesome_project.git", - "http_url": "http://example.com/awesome_space/awesome_project.git", - "visibility_level": 20, - "namespace": "awesome_space" - }, - "target": { - "name": "awesome_project", - "ssh_url": "ssh://git@example.com/awesome_space/awesome_project.git", - "http_url": "http://example.com/awesome_space/awesome_project.git", - "visibility_level": 20, - "namespace": "awesome_space" - }, - "last_commit": { - "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", - "message": "fixed readme", - "timestamp": "2012-01-03T23:36:29+02:00", - "url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", - "author": { - "name": "GitLab dev user", - "email": "gitlabdev@dv6700.(none)" - } - }, - "url": "http://example.com/diaspora/merge_requests/1", - "action": "open" - } -} -``` - -#### Example webhook receiver - -If you want to see GitLab's webhooks in action for testing purposes you can use -a simple echo script running in a console session. - -Save the following file as `print_http_body.rb`. - -```ruby -require 'webrick' - -server = WEBrick::HTTPServer.new(:Port => ARGV.first) -server.mount_proc '/' do |req, res| - puts req.body -end - -trap 'INT' do - server.shutdown -end -server.start -``` - -Pick an unused port (e.g. 8000) and start the script: `ruby print_http_body.rb -8000`. Then add your server as a webhook receiver in GitLab as -`http://my.host:8000/`. - -When you press 'Test Hook' in GitLab, you should see something like this in the console. - -``` -{"before":"077a85dd266e6f3573ef7e9ef8ce3343ad659c4e","after":"95cd4a99e93bc4bbabacfa2cd10e6725b1403c60",} -example.com - - [14/May/2014:07:45:26 EDT] "POST / HTTP/1.1" 200 0 -- -> / -``` diff --git a/doc/workflow/README.md b/doc/workflow/README.md deleted file mode 100644 index 7e996dc47d42cde6834b3a3692d4b51790ba234f..0000000000000000000000000000000000000000 --- a/doc/workflow/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Workflow - -- [Feature branch workflow](workflow.md) -- [Project forking workflow](forking_workflow.md) -- [Project Features](project_features.md) -- [Authorization for merge requests](authorization_for_merge_requests.md) -- [Groups](groups.md) -- [Labels](labels.md) -- [GitLab Flow](gitlab_flow.md) -- [Notifications](notifications.md) -- [Migrating from SVN to GitLab](migrating_from_svn.md) -- [Project importing from GitHub to GitLab](import_projects_from_github.md) -- [Project importing from GitLab.com to your private GitLab instance](import_projects_from_gitlab_com.md) -- [Protected branches](protected_branches.md) -- [Web Editor](web_editor.md) diff --git a/doc/workflow/authorization_for_merge_requests.md b/doc/workflow/authorization_for_merge_requests.md deleted file mode 100644 index d1d6d94ec11833256a6fb8af214b63d99cf9ab9d..0000000000000000000000000000000000000000 --- a/doc/workflow/authorization_for_merge_requests.md +++ /dev/null @@ -1,40 +0,0 @@ -# Authorization for Merge requests - -There are two main ways to have a merge request flow with GitLab: working with protected branches in a single repository, or working with forks of an authoritative project. - -## Protected branch flow - -With the protected branch flow everybody works within the same GitLab project. - -The project maintainers get Master access and the regular developers get Developer access. - -The maintainers mark the authoritative branches as 'Protected'. - -The developers push feature branches to the project and create merge requests to have their feature branches reviewed and merged into one of the protected branches. - -Only users with Master access can merge changes into a protected branch. - -### Advantages - -- fewer projects means less clutter -- developers need to consider only one remote repository - -### Disadvantages - -- manual setup of protected branch required for each new project - -## Forking workflow - -With the forking workflow the maintainers get Master access and the regular developers get Reporter access to the authoritative repository, which prohibits them from pushing any changes to it. - -Developers create forks of the authoritative project and push their feature branches to their own forks. - -To get their changes into master they need to create a merge request across forks. - -### Advantages - -- in an appropriately configured GitLab group, new projects automatically get the required access restrictions for regular developers: fewer manual steps to configure authorization for new projects - -### Disadvantages - -- the project need to keep their forks up to date, which requires more advanced Git skills (managing multiple remotes) diff --git a/doc/workflow/ci_mr.png b/doc/workflow/ci_mr.png deleted file mode 100644 index a577356f8e899d55dab9b9137010ac23320cd762..0000000000000000000000000000000000000000 Binary files a/doc/workflow/ci_mr.png and /dev/null differ diff --git a/doc/workflow/close_issue_mr.png b/doc/workflow/close_issue_mr.png deleted file mode 100644 index a136d642e125a782c8058417ff808b98159c0899..0000000000000000000000000000000000000000 Binary files a/doc/workflow/close_issue_mr.png and /dev/null differ diff --git a/doc/workflow/environment_branches.png b/doc/workflow/environment_branches.png deleted file mode 100644 index ee893ced13bd764322cc4195945403731508c9cb..0000000000000000000000000000000000000000 Binary files a/doc/workflow/environment_branches.png and /dev/null differ diff --git a/doc/workflow/forking/branch_select.png b/doc/workflow/forking/branch_select.png deleted file mode 100644 index 275f64d113baa4800fe6a49c366d5bb3c1237068..0000000000000000000000000000000000000000 Binary files a/doc/workflow/forking/branch_select.png and /dev/null differ diff --git a/doc/workflow/forking/fork_button.png b/doc/workflow/forking/fork_button.png deleted file mode 100644 index def4266476ad23531e7299ace79fa4e999b3d94c..0000000000000000000000000000000000000000 Binary files a/doc/workflow/forking/fork_button.png and /dev/null differ diff --git a/doc/workflow/forking/groups.png b/doc/workflow/forking/groups.png deleted file mode 100644 index 3ac64b3c8e746317376a7e0c6fa2b1df9e7a4569..0000000000000000000000000000000000000000 Binary files a/doc/workflow/forking/groups.png and /dev/null differ diff --git a/doc/workflow/forking/merge_request.png b/doc/workflow/forking/merge_request.png deleted file mode 100644 index 2dc00ed08a1df18629be937740f32ef35abbb87f..0000000000000000000000000000000000000000 Binary files a/doc/workflow/forking/merge_request.png and /dev/null differ diff --git a/doc/workflow/forking_workflow.md b/doc/workflow/forking_workflow.md deleted file mode 100644 index 8edf7c6ab3d203ea3389f18a28bf8d6b30974e82..0000000000000000000000000000000000000000 --- a/doc/workflow/forking_workflow.md +++ /dev/null @@ -1,36 +0,0 @@ -# Project forking workflow - -Forking a project to your own namespace is useful if you have no write access to the project you want to contribute -to. If you do have write access or can request it we recommend working together in the same repository since it is simpler. -See our **[GitLab Flow](https://about.gitlab.com/2014/09/29/gitlab-flow/)** article for more information about using -branches to work together. - -## Creating a fork - -In order to create a fork of a project, all you need to do is click on the fork button located on the top right side -of the screen, close to the project's URL and right next to the stars button. - -![Fork button](forking/fork_button.png) - -Once you do that you'll be presented with a screen where you can choose the namespace to fork to. Only namespaces -(groups and your own namespace) where you have write access to, will be shown. Click on the namespace to create your -fork there. - -![Groups view](forking/groups.png) - -After the forking is done, you can start working on the newly created repository. There you will have full -[Owner](../permissions/permissions.md) access, so you can set it up as you please. - -## Merging upstream - -Once you are ready to send your code back to the main project, you need to create a merge request. Choose your forked -project's main branch as the source and the original project's main branch as the destination and create the merge request. - -![Selecting branches](forking/branch_select.png) - -You can then assign the merge request to someone to have them review your changes. Upon pressing the 'Accept Merge Request' -button, your changes will be added to the repository and branch you're merging into. - -![New merge request](forking/merge_request.png) - - diff --git a/doc/workflow/four_stages.png b/doc/workflow/four_stages.png deleted file mode 100644 index 2f444fc6f7967772980948dfec8f779a204bf915..0000000000000000000000000000000000000000 Binary files a/doc/workflow/four_stages.png and /dev/null differ diff --git a/doc/workflow/git_pull.png b/doc/workflow/git_pull.png deleted file mode 100644 index 7d47064eb14176ccc23e472cbf1d9ea34f90d91f..0000000000000000000000000000000000000000 Binary files a/doc/workflow/git_pull.png and /dev/null differ diff --git a/doc/workflow/gitdashflow.png b/doc/workflow/gitdashflow.png deleted file mode 100644 index f2f091dd10b1b63a911977cdc4c059ac2f1925e6..0000000000000000000000000000000000000000 Binary files a/doc/workflow/gitdashflow.png and /dev/null differ diff --git a/doc/workflow/github_flow.png b/doc/workflow/github_flow.png deleted file mode 100644 index 88addb623ee0e554345dfbbde879e464befae85d..0000000000000000000000000000000000000000 Binary files a/doc/workflow/github_flow.png and /dev/null differ diff --git a/doc/workflow/github_importer/importer.png b/doc/workflow/github_importer/importer.png deleted file mode 100644 index 57636717571a17ea17ee5cfdabbd4408597fd668..0000000000000000000000000000000000000000 Binary files a/doc/workflow/github_importer/importer.png and /dev/null differ diff --git a/doc/workflow/github_importer/new_project_page.png b/doc/workflow/github_importer/new_project_page.png deleted file mode 100644 index 002f22d81d7d07eeece0deaec177b0dbc70745f6..0000000000000000000000000000000000000000 Binary files a/doc/workflow/github_importer/new_project_page.png and /dev/null differ diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md deleted file mode 100644 index 0e87dc74217d40e9df803c1b9b4988c12405f341..0000000000000000000000000000000000000000 --- a/doc/workflow/gitlab_flow.md +++ /dev/null @@ -1,316 +0,0 @@ -![GitLab Flow](gitlab_flow.png) - -## Introduction - -Version management with git makes branching and merging much easier than older versioning systems such as SVN. -This allows a wide variety of branching strategies and workflows. -Almost all of these are an improvement over the methods used before git. -But many organizations end up with a workflow that is not clearly defined, overly complex or not integrated with issue tracking systems. -Therefore we propose the GitLab flow as clearly defined set of best practices. -It combines [feature driven development](http://en.wikipedia.org/wiki/Feature-driven_development) and [feature branches](http://martinfowler.com/bliki/FeatureBranch.html) with issue tracking. - -Organizations coming to git from other version control systems frequently find it hard to develop an effective workflow. -This article describes the GitLab flow that integrates the git workflow with an issue tracking system. -It offers a simple, transparent and effective way to work with git. - -![Four stages (working copy, index, local repo, remote repo) and three steps between them](four_stages.png) - -When converting to git you have to get used to the fact that there are three steps before a commit is shared with colleagues. -Most version control systems have only step, committing from the working copy to a shared server. -In git you add files from the working copy to the staging area. After that you commit them to the local repo. -The third step is pushing to a shared remote repository. -After getting used to these three steps the branching model becomes the challenge. - -![Multiple long running branches and merging in all directions](messy_flow.png) - -Since many organizations new to git have no conventions how to work with it, it can quickly become a mess. -The biggest problem they run into is that many long running branches that each contain part of the changes are around. -People have a hard time figuring out which branch they should develop on or deploy to production. -Frequently the reaction to this problem is to adopt a standardized pattern such as [git flow](http://nvie.com/posts/a-successful-git-branching-model/) and [GitHub flow](http://scottchacon.com/2011/08/31/github-flow.html) -We think there is still room for improvement and will detail a set of practices we call GitLab flow. - -## Git flow and its problems - -[![Git Flow timeline by Vincent Driessen, used with permission](gitdashflow.png) - -Git flow was one of the first proposals to use git branches and it has gotten a lot of attention. -It advocates a master branch and a separate develop branch as well as supporting branches for features, releases and hotfixes. -The development happens on the develop branch, moves to a release branch and is finally merged into the master branch. -Git flow is a well defined standard but its complexity introduces two problems. -The first problem is that developers must use the develop branch and not master, master is reserved for code that is released to production. -It is a convention to call your default branch master and to mostly branch from and merge to this. -Since most tools automatically make the master branch the default one and display that one by default it is annoying to have to switch to another one. -The second problem of git flow is the complexity introduced by the hotfix and release branches. -These branches can be a good idea for some organizations but are overkill for the vast majority of them. -Nowadays most organizations practice continuous delivery which means that your default branch can be deployed. -This means that hotfix and release branches can be prevented including all the ceremony they introduce. -An example of this ceremony is the merging back of release branches. -Though specialized tools do exist to solve this, they require documentation and add complexity. -Frequently developers make a mistake and for example changes are only merged into master and not into the develop branch. -The root cause of these errors is that git flow is too complex for most of the use cases. -And doing releases doesn't automatically mean also doing hotfixes. - -## GitHub flow as a simpler alternative - -![Master branch with feature branches merged in](github_flow.png) - - In reaction to git flow a simpler alternative was detailed, [GitHub flow](https://guides.github.com/introduction/flow/index.html). -This flow has only feature branches and a master branch. -This is very simple and clean, many organizations have adopted it with great success. -Atlassian recommends [a similar strategy](http://blogs.atlassian.com/2014/01/simple-git-workflow-simple/) although they rebase feature branches. -Merging everything into the master branch and deploying often means you minimize the amount of code in 'inventory' which is in line with the lean and continuous delivery best practices. -But this flow still leaves a lot of questions unanswered regarding deployments, environments, releases and integrations with issues. -With GitLab flow we offer additional guidance for these questions. - -## Production branch with GitLab flow - -![Master branch and production branch with arrow that indicate deployments](production_branch.png) - -GitHub flow does assume you are able to deploy to production every time you merge a feature branch. -This is possible for SaaS applications but are many cases where this is not possible. -One would be a situation where you are not in control of the exact release moment, for example an iOS application that needs to pass App Store validation. -Another example is when you have deployment windows (workdays from 10am to 4pm when the operations team is at full capacity) but you also merge code at other times. -In these cases you can make a production branch that reflects the deployed code. -You can deploy a new version by merging in master to the production branch. -If you need to know what code is in production you can just checkout the production branch to see. -The approximate time of deployment is easily visible as the merge commit in the version control system. -This time is pretty accurate if you automatically deploy your production branch. -If you need a more exact time you can have your deployment script create a tag on each deployment. -This flow prevents the overhead of releasing, tagging and merging that is common to git flow. - -## Environment branches with GitLab flow - -![Multiple branches with the code cascading from one to another](environment_branches.png) - -It might be a good idea to have an environment that is automatically updated to the master branch. -Only in this case, the name of this environment might differ from the branch name. -Suppose you have a staging environment, a pre-production environment and a production environment. -In this case the master branch is deployed on staging. When someone wants to deploy to pre-production they create a merge request from the master branch to the pre-production branch. -And going live with code happens by merging the pre-production branch into the production branch. -This workflow where commits only flow downstream ensures that everything has been tested on all environments. -If you need to cherry-pick a commit with a hotfix it is common to develop it on a feature branch and merge it into master with a merge request, do not delete the feature branch. -If master is good to go (it should be if you a practicing [continuous delivery](http://martinfowler.com/bliki/ContinuousDelivery.html)) you then merge it to the other branches. -If this is not possible because more manual testing is required you can send merge requests from the feature branch to the downstream branches. -An 'extreme' version of environment branches are setting up an environment for each feature branch as done by [Teatro](http://teatro.io/). - -## Release branches with GitLab flow - -![Master and multiple release branches that vary in length with cherry-picks from master](release_branches.png) - -Only in case you need to release software to the outside world you need to work with release branches. -In this case, each branch contains a minor version (2-3-stable, 2-4-stable, etc.). -The stable branch uses master as a starting point and is created as late as possible. -By branching as late as possible you minimize the time you have to apply bug fixes to multiple branches. -After a release branch is announced, only serious bug fixes are included in the release branch. -If possible these bug fixes are first merged into master and then cherry-picked into the release branch. -This way you can't forget to cherry-pick them into master and encounter the same bug on subsequent releases. -This is called an 'upstream first' policy that is also practiced by [Google](http://www.chromium.org/chromium-os/chromiumos-design-docs/upstream-first) and [Red Hat](http://www.redhat.com/about/news/archive/2013/5/a-community-for-using-openstack-with-red-hat-rdo). -Every time a bug-fix is included in a release branch the patch version is raised (to comply with [Semantic Versioning](http://semver.org/)) by setting a new tag. -Some projects also have a stable branch that points to the same commit as the latest released branch. -In this flow it is not common to have a production branch (or git flow master branch). - -## Merge/pull requests with GitLab flow - -![Merge request with line comments](mr_inline_comments.png) - -Merge or pull requests are created in a git management application and ask an assigned person to merge two branches. -Tools such as GitHub and Bitbucket choose the name pull request since the first manual action would be to pull the feature branch. -Tools such as GitLab and Gitorious choose the name merge request since that is the final action that is requested of the assignee. -In this article we'll refer to them as merge requests. - -If you work on a feature branch for more than a few hours it is good to share the intermediate result with the rest of the team. -This can be done by creating a merge request without assigning it to anyone, instead you mention people in the description or a comment (/cc @mark @susan). -This means it is not ready to be merged but feedback is welcome. -Your team members can comment on the merge request in general or on specific lines with line comments. -The merge requests serves as a code review tool and no separate tools such as Gerrit and reviewboard should be needed. -If the review reveals shortcomings anyone can commit and push a fix. -Commonly the person to do this is the creator of the merge/pull request. -The diff in the merge/pull requests automatically updates when new commits are pushed on the branch. - -When you feel comfortable with it to be merged you assign it to the person that knows most about the codebase you are changing and mention any other people you would like feedback from. -There is room for more feedback and after the assigned person feels comfortable with the result the branch is merged. -If the assigned person does not feel comfortable they can close the merge request without merging. - -In GitLab it is common to protect the long-lived branches (e.g. the master branch) so that normal developers [can't modify these protected branches](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/permissions/permissions.md). -So if you want to merge it into a protected branch you assign it to someone with master authorizations. - -## Issues with GitLab flow - -![Merge request with the branch name 15-require-a-password-to-change-it and assignee field shown](merge_request.png) - -GitLab flow is a way to make the relation between the code and the issue tracker more transparent. - -Any significant change to the code should start with an issue where the goal is described. -Having a reason for every code change is important to inform everyone on the team and to help people keep the scope of a feature branch small. -In GitLab each change to the codebase starts with an issue in the issue tracking system. -If there is no issue yet it should be created first provided there is significant work involved (more than 1 hour). -For many organizations this will be natural since the issue will have to be estimated for the sprint. -Issue titles should describe the desired state of the system, e.g. "As an administrator I want to remove users without receiving an error" instead of "Admin can't remove users.". - -When you are ready to code you start a branch for the issue from the master branch. -The name of this branch should start with the issue number, for example '15-require-a-password-to-change-it'. - -When you are done or want to discuss the code you open a merge request. -This is an online place to discuss the change and review the code. -Creating a branch is a manual action since you do not always want to merge a new branch you push, it could be a long-running environment or release branch. -If you create the merge request but do not assign it to anyone it is a 'work-in-process' merge request. -These are used to discuss the proposed implementation but are not ready for inclusion in the master branch yet. - -When the author thinks the code is ready the merge request is assigned to reviewer. -The reviewer presses the merge button when they think the code is ready for inclusion in the master branch. -In this case the code is merged and a merge commit is generated that makes this event easily visible later on. -Merge requests always create a merge commit even when the commit could be added without one. -This merge strategy is called 'no fast-forward' in git. -After the merge the feature branch is deleted since it is no longer needed, in GitLab this deletion is an option when merging. - -Suppose that a branch is merged but a problem occurs and the issue is reopened. -In this case it is no problem to reuse the same branch name since it was deleted when the branch was merged. -At any time there is at most one branch for every issue. -It is possible that one feature branch solves more than one issue. - -## Linking and closing issues from merge requests - -![Merge request showing the linked issues that will be closed](close_issue_mr.png) - -Linking to the issue can happen by mentioning them from commit messages (fixes #14, closes #67, etc.) or from the merge request description. -In GitLab this creates a comment in the issue that the merge requests mentions the issue. -And the merge request shows the linked issues. -These issues are closed once code is merged into the default branch. - -If you only want to make the reference without closing the issue you can also just mention it: "Duck typing is preferred. #12". - -If you have an issue that spans across multiple repositories, the best thing is to create an issue for each repository and link all issues to a parent issue. - -## Squashing commits with rebase - -![Vim screen showing the rebase view](rebase.png) - -With git you can use an interactive rebase (rebase -i) to squash multiple commits into one and reorder them. -This functionality is useful if you made a couple of commits for small changes during development and want to replace them with a single commit or if you want to make the order more logical. -However you should never rebase commits you have pushed to a remote server. -Somebody can have referred to the commits or cherry-picked them. -When you rebase you change the identifier (SHA-1) of the commit and this is confusing. -If you do that the same change will be known under multiple identifiers and this can cause much confusion. -If people already reviewed your code it will be hard for them to review only the improvements you made since then if you have rebased everything into one commit. - -People are encouraged to commit often and to frequently push to the remote repository so other people are aware what everyone is working on. -This will lead to many commits per change which makes the history harder to understand. -But the advantages of having stable identifiers outweigh this drawback. -And to understand a change in context one can always look at the merge commit that groups all the commits together when the code is merged into the master branch. - -After you merge multiple commits from a feature branch into the master branch this is harder to undo. -If you would have squashed all the commits into one you could have just reverted this commit but as we indicated you should not rebase commits after they are pushed. -Fortunately [reverting a merge made some time ago](http://git-scm.com/blog/2010/03/02/undoing-merges.html) can be done with git. -This however, requires having specific merge commits for the commits your want to revert. -If you revert a merge and you change your mind, revert the revert instead of merging again since git will not allow you to merge the code again otherwise. - -Being able to revert a merge is a good reason always to create a merge commit when you merge manually with the `--no-ff` option. -Git management software will always create a merge commit when you accept a merge request. - -## Do not order commits with rebase - -![List of sequential merge commits](merge_commits.png) - -With git you can also rebase your feature branch commits to order them after the commits on the master branch. -This prevents creating a merge commit when merging master into your feature branch and creates a nice linear history. -However, just like with squashing you should never rebase commits you have pushed to a remote server. -This makes it impossible to rebase work in progress that you already shared with your team which is something we recommend. -When using rebase to keep your feature branch updated you [need to resolve similar conflicts again and again](http://blogs.atlassian.com/2013/10/git-team-workflows-merge-or-rebase/). -You can reuse recorded resolutions (rerere) sometimes, but with without rebasing you only have to solve the conflicts one time and you’re set. -There has to be a better way to avoid many merge commits. - -The way to prevent creating many merge commits is to not frequently merge master into the feature branch. -We'll discuss the three reasons to merge in master: leveraging code, solving merge conflicts and long running branches. -If you need to leverage some code that was introduced in master after you created the feature branch you can sometimes solve this by just cherry-picking a commit. -If your feature branch has a merge conflict, creating a merge commit is a normal way of solving this. -You should aim to prevent merge conflicts where they are likely to occur. -One example is the CHANGELOG file where each significant change in the codebase is documented under a version header. -Instead of everyone adding their change at the bottom of the list for the current version it is better to randomly insert it in the current list for that version. -This it is likely that multiple feature branches that add to the CHANGELOG can be merged before a conflict occurs. -The last reason for creating merge commits is having long lived branches that you want to keep up to date with the latest state of the project. -Martin Fowler, in [his article about feature branches](http://martinfowler.com/bliki/FeatureBranch.html) talks about this Continuous Integration (CI). -At GitLab we are guilty of confusing CI with branch testing. Quoting Martin Fowler: "I've heard people say they are doing CI because they are running builds, perhaps using a CI server, on every branch with every commit. -That's continuous building, and a Good Thing, but there's no integration, so it's not CI.". -The solution to prevent many merge commits is to keep your feature branches short-lived, the vast majority should take less than one day of work. -If your feature branches commonly take more than a day of work, look into ways to create smaller units of work and/or use [feature toggles](http://martinfowler.com/bliki/FeatureToggle.html). -As for the long running branches that take more than one day there are two strategies. -In a CI strategy you can merge in master at the start of the day to prevent painful merges at a later time. -In a synchronization point strategy you only merge in from well defined points in time, for example a tagged release. -This strategy is [advocated by Linus Torvalds](https://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html) because the state of the code at these points is better known. - -In conclusion, we can say that you should try to prevent merge commits, but not eliminate them. -Your codebase should be clean but your history should represent what actually happened. -Developing software happen in small messy steps and it is OK to have your history reflect this. -You can use tools to view the network graphs of commits and understand the messy history that created your code. -If you rebase code the history is incorrect, and there is no way for tools to remedy this because they can't deal with changing commit identifiers. - -## Voting on merge requests - -![Voting slider in GitLab](voting_slider.png) - -It is common to voice approval or disapproval by using +1 or -1 emoticons. -In GitLab the +1 and -1 are aggregated and shown at the top of the merge request. -As a rule of thumb anything that doesn't have two times more +1's than -1's is suspect and should not be merged yet. - -## Pushing and removing branches - -![Remove checkbox for branch in merge requests](remove_checkbox.png) - -We recommend that people push their feature branches frequently, even when they are not ready for review yet. -By doing this you prevent team members from accidentally starting to work on the same issue. -Of course this situation should already be prevented by assigning someone to the issue in the issue tracking software. -However sometimes one of the two parties forgets to assign someone in the issue tracking software. -After a branch is merged it should be removed from the source control software. -In GitLab and similar systems this is an option when merging. -This ensures that the branch overview in the repository management software shows only work in progress. -This also ensures that when someone reopens the issue a new branch with the same name can be used without problem. -When you reopen an issue you need to create a new merge request. - -## Committing often and with the right message - -![Good and bad commit message](good_commit.png) - -We recommend to commit early and often. -Each time you have a functioning set of tests and code a commit can be made. -The advantage is that when an extension or refactor goes wrong it is easy to revert to a working version. -This is quite a change for programmers that used SVN before, they used to commit when their work was ready to share. -The trick is to use the merge/pull request with multiple commits when your work is ready to share. -The commit message should reflect your intention, not the contents of the commit. -The contents of the commit can be easily seen anyway, the question is why you did it. -An example of a good commit message is: "Combine templates to dry up the user views.". -Some words that are bad commit messages because they don't contain munch information are: change, improve and refactor. -The word fix or fixes is also a red flag, unless it comes after the commit sentence and references an issue number. -To see more information about the formatting of commit messages please see this great [blog post by Tim Pope](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). - -## Testing before merging - -![Merge requests showing the test states, red, yellow and green](ci_mr.png) - -In old workflows the Continuous Integration (CI) server commonly ran tests on the master branch only. -Developers had to ensure their code did not break the master branch. -When using GitLab flow developers create their branches from this master branch so it is essential it is green. -Therefore each merge request must be tested before it is accepted. -CI software like Travis and GitLab CI show the build results right in the merge request itself to make this easy. -One drawback is that they are testing the feature branch itself and not the merged result. -What one can do to improve this is to test the merged result itself. -The problem is that the merge result changes every time something is merged into master. -Retesting on every commit to master is computationally expensive and means you are more frequently waiting for test results. -If there are no merge conflicts and the feature branches are short lived the risk is acceptable. -If there are merge conflicts you merge the master branch into the feature branch and the CI server will rerun the tests. -If you have long lived feature branches that last for more than a few days you should make your issues smaller. - -## Merging in other code - -![Shell output showing git pull output](git_pull.png) - -When initiating a feature branch, always start with an up to date master to branch off from. -If you know beforehand that your work absolutely depends on another branch you can also branch from there. -If you need to merge in another branch after starting explain the reason in the merge commit. -If you have not pushed your commits to a shared location yet you can also rebase on master or another feature branch. -Do not merge in upstream if your code will work and merge cleanly without doing so, Linus even says that [you should never merge in upstream at random points, only at major releases](http://lwn.net/Articles/328438/). -Merging only when needed prevents creating merge commits in your feature branch that later end up littering the master history. - -### References - -- [Sketch file](https://www.dropbox.com/s/58dvsj5votbwrzv/git_flows.sketch?dl=0) with vectors of images in this article -- [Git Flow by Vincent Driessen](http://nvie.com/posts/a-successful-git-branching-model/) diff --git a/doc/workflow/gitlab_flow.png b/doc/workflow/gitlab_flow.png deleted file mode 100644 index 1ea191a672b7cb177687cfa6e93dca43af8b8c55..0000000000000000000000000000000000000000 Binary files a/doc/workflow/gitlab_flow.png and /dev/null differ diff --git a/doc/workflow/gitlab_importer/importer.png b/doc/workflow/gitlab_importer/importer.png deleted file mode 100644 index d2a286d8cac32caf6594537b6842ebdcfaedee58..0000000000000000000000000000000000000000 Binary files a/doc/workflow/gitlab_importer/importer.png and /dev/null differ diff --git a/doc/workflow/gitlab_importer/new_project_page.png b/doc/workflow/gitlab_importer/new_project_page.png deleted file mode 100644 index 5e239208e1e73ec80d5ff16eced9ea371b721df2..0000000000000000000000000000000000000000 Binary files a/doc/workflow/gitlab_importer/new_project_page.png and /dev/null differ diff --git a/doc/workflow/good_commit.png b/doc/workflow/good_commit.png deleted file mode 100644 index 3737a0266445e6714980a693a7b031e678ad841a..0000000000000000000000000000000000000000 Binary files a/doc/workflow/good_commit.png and /dev/null differ diff --git a/doc/workflow/groups.md b/doc/workflow/groups.md deleted file mode 100644 index 52bf611dc5e2a83ee68a46b616b71de77f88e970..0000000000000000000000000000000000000000 --- a/doc/workflow/groups.md +++ /dev/null @@ -1,71 +0,0 @@ -# GitLab Groups - -GitLab groups allow you to group projects into directories and give users to several projects at once. - -When you create a new project in GitLab, the default namespace for the project is the personal namespace associated with your GitLab user. -In this document we will see how to create groups, put projects in groups and manage who can access the projects in a group. - -## Creating groups - -You can create a group by going to the 'Groups' tab of the GitLab dashboard and clicking the 'New group' button. - -![Click the 'New group' button in the 'Groups' tab](groups/new_group_button.png) - -Next, enter the name (required) and the optional description and group avatar. - -![Fill in the name for your new group](groups/new_group_form.png) - -When your group has been created you are presented with the group dashboard feed, which will be empty. - -![Group dashboard](groups/group_dashboard.png) - -You can use the 'New project' button to add a project to the new group. - -## Transferring an existing project into a group - -You can transfer an existing project into a group you own from the project settings page. -First scroll down to the 'Dangerous settings' and click 'Show them to me'. -Now you can pick any of the groups you manage as the new namespace for the group. - -![Transfer a project to a new namespace](groups/transfer_project.png) - -GitLab administrators can use the admin interface to move any project to any namespace if needed. - -## Adding users to a group - -One of the benefits of putting multiple projects in one group is that you can give a user to access to all projects in the group with one action. - -Suppose we have a group with two projects. - -![Group with two projects](groups/group_with_two_projects.png) - -On the 'Group Members' page we can now add a new user Barry to the group. - -![Add user Barry to the group](groups/add_member_to_group.png) - -Now because Barry is a 'Developer' member of the 'Open Source' group, he automatically gets 'Developer' access to all projects in the 'Open Source' group. - -![Barry has 'Developer' access to GitLab CI](groups/project_members_via_group.png) - -If necessary, you can increase the access level of an individual user for a specific project, by adding them as a Member to the project. - -![Barry effectively has 'Master' access to GitLab CI now](groups/override_access_level.png) - -## Managing group memberships via LDAP - -In GitLab Enterprise Edition it is possible to manage GitLab group memberships using LDAP groups. -See [the GitLab Enterprise Edition documentation](http://doc.gitlab.com/ee/integration/ldap.html) for more information. - -## Allowing only admins to create groups - -By default, any GitLab user can create new groups. -This ability can be disabled for individual users from the admin panel. -It is also possible to configure GitLab so that new users default to not being able to create groups: - -``` -# For omnibus-gitlab, put the following in /etc/gitlab/gitlab.rb -gitlab_rails['gitlab_default_can_create_group'] = false - -# For installations from source, uncomment the 'default_can_create_group' -# line in /home/git/gitlab/config/gitlab.yml -``` diff --git a/doc/workflow/groups/add_member_to_group.png b/doc/workflow/groups/add_member_to_group.png deleted file mode 100644 index fa340ce572f0804186abc0454c682bf16ebb524e..0000000000000000000000000000000000000000 Binary files a/doc/workflow/groups/add_member_to_group.png and /dev/null differ diff --git a/doc/workflow/groups/group_dashboard.png b/doc/workflow/groups/group_dashboard.png deleted file mode 100644 index 7fc9048d74d6f59798693bebd219060db1a82755..0000000000000000000000000000000000000000 Binary files a/doc/workflow/groups/group_dashboard.png and /dev/null differ diff --git a/doc/workflow/groups/group_with_two_projects.png b/doc/workflow/groups/group_with_two_projects.png deleted file mode 100644 index 87242781e4fd492a85adf0f13a9679296808d5b1..0000000000000000000000000000000000000000 Binary files a/doc/workflow/groups/group_with_two_projects.png and /dev/null differ diff --git a/doc/workflow/groups/new_group_button.png b/doc/workflow/groups/new_group_button.png deleted file mode 100644 index 51e827986586ca471c99999680f0688459124c13..0000000000000000000000000000000000000000 Binary files a/doc/workflow/groups/new_group_button.png and /dev/null differ diff --git a/doc/workflow/groups/new_group_form.png b/doc/workflow/groups/new_group_form.png deleted file mode 100644 index bf992c40bc2b08fc1d70783552871480a263bedb..0000000000000000000000000000000000000000 Binary files a/doc/workflow/groups/new_group_form.png and /dev/null differ diff --git a/doc/workflow/groups/override_access_level.png b/doc/workflow/groups/override_access_level.png deleted file mode 100644 index f4225a63679324d1d6c4a1093163a8b0b2bd67c0..0000000000000000000000000000000000000000 Binary files a/doc/workflow/groups/override_access_level.png and /dev/null differ diff --git a/doc/workflow/groups/project_members_via_group.png b/doc/workflow/groups/project_members_via_group.png deleted file mode 100644 index b13cb1cfd9528a501d2ee2a6802f77ed365fadb5..0000000000000000000000000000000000000000 Binary files a/doc/workflow/groups/project_members_via_group.png and /dev/null differ diff --git a/doc/workflow/groups/transfer_project.png b/doc/workflow/groups/transfer_project.png deleted file mode 100644 index 044fe10d07337adedd8078f26bf42e0b4381eaab..0000000000000000000000000000000000000000 Binary files a/doc/workflow/groups/transfer_project.png and /dev/null differ diff --git a/doc/workflow/import_projects_from_github.md b/doc/workflow/import_projects_from_github.md deleted file mode 100644 index 8644b4ffc73c23cb356fdee969de9aceef8dac91..0000000000000000000000000000000000000000 --- a/doc/workflow/import_projects_from_github.md +++ /dev/null @@ -1,13 +0,0 @@ -# Project importing from GitHub to GitLab - -You can import your existing GitHub projects to GitLab. But keep in mind that it is possible only if -GitHub support is enabled on your GitLab instance. You can read more about GitHub support [here](http://doc.gitlab.com/ce/integration/github.html) -To get to the importer page you need to go to "New project" page. - -![New project page](github_importer/new_project_page.png) - -Click on the "Import project from GitHub" link and you will be redirected to GitHub for permission to access your projects. After accepting, you'll be automatically redirected to the importer. - -![Importer page](github_importer/importer.png) - -To import a project, you can simple click "Add". The importer will import your repository and issues. Once the importer is done, a new GitLab project will be created with your imported data. \ No newline at end of file diff --git a/doc/workflow/import_projects_from_gitlab_com.md b/doc/workflow/import_projects_from_gitlab_com.md deleted file mode 100644 index f4c4e955d46982c9d54291deb9c3902ba4ff6c4a..0000000000000000000000000000000000000000 --- a/doc/workflow/import_projects_from_gitlab_com.md +++ /dev/null @@ -1,18 +0,0 @@ -# Project importing from GitLab.com to your private GitLab instance - -You can import your existing GitLab.com projects to your GitLab instance. But keep in mind that it is possible only if -GitLab support is enabled on your GitLab instance. -You can read more about Gitlab support [here](http://doc.gitlab.com/ce/integration/gitlab.html) -To get to the importer page you need to go to "New project" page. - -![New project page](gitlab_importer/new_project_page.png) - -Click on the "Import projects from Gitlab.com" link and you will be redirected to GitLab.com -for permission to access your projects. After accepting, you'll be automatically redirected to the importer. - - -![Importer page](gitlab_importer/importer.png) - - -To import a project, you can simple click "Import". The importer will import your repository and issues. -Once the importer is done, a new GitLab project will be created with your imported data. \ No newline at end of file diff --git a/doc/workflow/labels.md b/doc/workflow/labels.md deleted file mode 100644 index 085b7baf5ceed6bdfcbc9e7b44d1eef97d6bd208..0000000000000000000000000000000000000000 --- a/doc/workflow/labels.md +++ /dev/null @@ -1,16 +0,0 @@ -# Labels - -In GitLab, you can easily tag issues and merge requests. If you have permission level `Developer` or higher, you can manage labels. To create, edit or delete a label, go to a project and then to `Issues` and then `Labels`. - -Here you can create a new label. - -![new label](labels/label1.png) - -You can choose to set a color. - -![label color](labels/label2.png) - -If you want to change an existing label, press edit next to the listed label. -You will be presented with the same form as when creating a new label. - -![edit label](labels/label3.png) diff --git a/doc/workflow/labels/label1.png b/doc/workflow/labels/label1.png deleted file mode 100644 index cac661a34c8c393438130096b7fe78c4d996c9c9..0000000000000000000000000000000000000000 Binary files a/doc/workflow/labels/label1.png and /dev/null differ diff --git a/doc/workflow/labels/label2.png b/doc/workflow/labels/label2.png deleted file mode 100644 index 44d9fef86d4d32568d301843f674d4bda73bf99e..0000000000000000000000000000000000000000 Binary files a/doc/workflow/labels/label2.png and /dev/null differ diff --git a/doc/workflow/labels/label3.png b/doc/workflow/labels/label3.png deleted file mode 100644 index e2fce11b7a42be3d0b6c99fdf45f741b5ac3088c..0000000000000000000000000000000000000000 Binary files a/doc/workflow/labels/label3.png and /dev/null differ diff --git a/doc/workflow/merge_commits.png b/doc/workflow/merge_commits.png deleted file mode 100644 index 757b589d0dbb71c56b56905eb9fb1af895d859b6..0000000000000000000000000000000000000000 Binary files a/doc/workflow/merge_commits.png and /dev/null differ diff --git a/doc/workflow/merge_request.png b/doc/workflow/merge_request.png deleted file mode 100644 index fde3ff5c854f877e2a621f6b15ee1c6ed7ac5a8d..0000000000000000000000000000000000000000 Binary files a/doc/workflow/merge_request.png and /dev/null differ diff --git a/doc/workflow/messy_flow.png b/doc/workflow/messy_flow.png deleted file mode 100644 index 1addb95ca5455fc9ea12da3868c322a9e5fdaa01..0000000000000000000000000000000000000000 Binary files a/doc/workflow/messy_flow.png and /dev/null differ diff --git a/doc/workflow/migrating_from_svn.md b/doc/workflow/migrating_from_svn.md deleted file mode 100644 index 485db4834e97c635d546cbfeb02c14e893051cfd..0000000000000000000000000000000000000000 --- a/doc/workflow/migrating_from_svn.md +++ /dev/null @@ -1,17 +0,0 @@ -# Migrating from SVN to GitLab - -SVN stands for Subversion and is a version control system (VCS). -Git is a distributed version control system. - -There are some major differences between the two, for more information consult your favorite search engine. - -Git has tools for migrating SVN repositories to git, namely `git svn`. You can read more about this at -[git documentation pages](http://git-scm.com/book/en/Git-and-Other-Systems-Git-and-Subversion). - -Apart from the [official git documentation](http://git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git) there is also -user created step by step guide for migrating from SVN to GitLab. - -[Benjamin New](https://github.com/leftclickben) wrote [a guide that shows how to do a migration](https://gist.github.com/leftclickben/322b7a3042cbe97ed2af). Mirrors can be found [here](https://gitlab.com/snippets/2168) and [here](https://gist.github.com/maxlazio/f1b593b0d00aa966e9ca). - -## Contribute to this guide -We welcome all contributions that would expand this guide with instructions on how to migrate from SVN and other version control systems. diff --git a/doc/workflow/mr_inline_comments.png b/doc/workflow/mr_inline_comments.png deleted file mode 100644 index e851b95bcefff033e075d76221c29f2541a38245..0000000000000000000000000000000000000000 Binary files a/doc/workflow/mr_inline_comments.png and /dev/null differ diff --git a/doc/workflow/notifications.md b/doc/workflow/notifications.md deleted file mode 100644 index 17215de677e153d2aedfae3f91f7f51b0a57f2f1..0000000000000000000000000000000000000000 --- a/doc/workflow/notifications.md +++ /dev/null @@ -1,71 +0,0 @@ -# GitLab Notifications - -GitLab has notifications system in place to notify a user of events important for the workflow. - -## Notification settings - -Under user profile page you can find the notification settings. - -![notification settings](notifications/settings.png) - -Notification settings are divided into three groups: - -* Global Settings -* Group Settings -* Project Settings - -Each of these settings have levels of notification: - -* Disabled - turns off notifications -* Participating - receive notifications from related resources -* Watch - receive notifications from projects or groups user is a member of -* Global - notifications as set at the global settings - -#### Global Settings - -Global Settings are at the bottom of the hierarchy. -Any setting set here will be overridden by a setting at the group or a project level. - -Group or Project settings can use `global` notification setting which will then use -anything that is set at Global Settings. - -#### Group Settings - -Group Settings are taking precedence over Global Settings but are on a level below Project Settings. -This means that you can set a different level of notifications per group while still being able -to have a finer level setting per project. -Organization like this is suitable for users that belong to different groups but don't have the -same need for being notified for every group they are member of. - -#### Project Settings - -Project Settings are at the top level and any setting placed at this level will take precedence of any -other setting. -This is suitable for users that have different needs for notifications per project basis. - -## Notification events - -Below is the table of events users can be notified of: - -| Event | Sent to | Settings level | -|------------------------------|-------------------------------------------------------------------|------------------------------| -| New SSH key added | User | Security email, always sent. | -| New email added | User | Security email, always sent. | -| New user created | User | Sent on user creation, except for omniauth (LDAP)| -| New issue created | Issue assignee [1], project members [2] | [1] not disabled, [2] higher than participating | -| User added to project | User | Sent when user is added to project | -| Project access level changed | User | Sent when user project access level is changed | -| User added to group | User | Sent when user is added to group | -| Project moved | Project members [1] | [1] not disabled | -| Group access level changed | User | Sent when user group access level is changed | -| Close issue | Issue author [1], issue assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating | -| Reassign issue | New issue assignee [1], old issue assignee [2] | [1] [2] not disabled | -| Reopen issue | Project members [1] | [1] higher than participating | -| New merge request | MR assignee [1] | [1] not disabled | -| Reassign merge request | New MR assignee [1], old MR assignee [2] | [1] [2] not disabled | -| Close merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating | -| Reopen merge request | Project members [1] | [1] higher than participating | -| Merge merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating | -| New comment | Mentioned users [1], users participating [2], project members [3] | [1] [2] not disabled, [3] higher than participating | - - diff --git a/doc/workflow/notifications/settings.png b/doc/workflow/notifications/settings.png deleted file mode 100644 index e5b50ee249478f8d5cd3601e801fe7b7d93d10c2..0000000000000000000000000000000000000000 Binary files a/doc/workflow/notifications/settings.png and /dev/null differ diff --git a/doc/workflow/production_branch.png b/doc/workflow/production_branch.png deleted file mode 100644 index 33fb26dd62163cc5d9436a91db508971e73fc1f5..0000000000000000000000000000000000000000 Binary files a/doc/workflow/production_branch.png and /dev/null differ diff --git a/doc/workflow/project_features.md b/doc/workflow/project_features.md deleted file mode 100644 index a523b3facbe317030977849f3e15c18d723309b7..0000000000000000000000000000000000000000 --- a/doc/workflow/project_features.md +++ /dev/null @@ -1,35 +0,0 @@ -# Project features - -When in a Project -> Settings, you will find Features on the bottom of the page that you can toggle. - -Below you will find a more elaborate explanation of each of these. - -## Issues - -Issues is a really powerful, but lightweight issue tracking system. - -You can make tickets, assign them to people, file them under milestones, order them with labels and have discussion in them. - -They integrate deeply into GitLab and are easily referenced from anywhere by using `#` and the issue number. - -## Merge Requests - -Using a merge request, you can review and discuss code before it is merged in the branch of your code. - -As with issues, it can be assigned; people, issues, etc. can be referenced; milestones attached. - -We see it as an integral part of working together on code and couldn't work without it. - -## Wiki - -This is a separate system for documentation, built right into GitLab. - -It is source controlled and is very convenient if you don't want to keep you documentation in your source code, but you do want to keep it in your GitLab project. - -## Snippets - -Snippets are little bits of code or text. - -This is a nice place to put code or text that is used semi-regularly within the project, but does not belong in source control. - -For example, a specific config file that is used by > the team that is only valid for the people that work on the code. diff --git a/doc/workflow/protected_branches.md b/doc/workflow/protected_branches.md deleted file mode 100644 index 805f7f8d35c46e130836174c48b10770cadf0cb8..0000000000000000000000000000000000000000 --- a/doc/workflow/protected_branches.md +++ /dev/null @@ -1,33 +0,0 @@ -# Protected branches - -Permission in GitLab are fundamentally defined around the idea of having read or write permission to the repository and branches. - -To prevent people from messing with history or pushing code without review, we've created protected branches. - -A protected branch does three simple things: - -* it prevents pushes from everybody except users with Master permission -* it prevents anyone from force pushing to the branch -* it prevents anyone from deleting the branch - -You can make any branch a protected branch. GitLab makes the master branch a protected branch by default. - -To protect a branch, user needs to have at least a Master permission level, see [permissions document](permissions/permissions.md). - -![protected branches page](protected_branches/protected_branches1.png) - -Navigate to project settings page and select `protected branches`. From the `Branch` dropdown menu select the branch you want to protect. - -Some workflows, like [GitLab workflow](gitlab_flow.md), require all users with write access to submit a Merge request in order to get the code into a protected branch. - -Since Masters and Owners can already push to protected branches, that means Developers cannot push to protected branch and need to submit a Merge request. - -However, there are workflows where that is not needed and only protecting from force pushes and branch removal is useful. - -For those workflows, you can allow everyone with write access to push to a protected branch by selecting `Developers can push` check box. - -On already protected branches you can also allow developers to push to the repository by selecting the `Developers can push` check box. - -![Developers can push](protected_branches/protected_branches2.png) - - diff --git a/doc/workflow/protected_branches/protected_branches1.png b/doc/workflow/protected_branches/protected_branches1.png deleted file mode 100644 index 5c2a3de5f7043225788bb65cf35652525a0bb357..0000000000000000000000000000000000000000 Binary files a/doc/workflow/protected_branches/protected_branches1.png and /dev/null differ diff --git a/doc/workflow/protected_branches/protected_branches2.png b/doc/workflow/protected_branches/protected_branches2.png deleted file mode 100644 index 2dca35413655a79768911db229db1462e5397018..0000000000000000000000000000000000000000 Binary files a/doc/workflow/protected_branches/protected_branches2.png and /dev/null differ diff --git a/doc/workflow/rebase.png b/doc/workflow/rebase.png deleted file mode 100644 index ef82c834755c7b3e2c53145418c461044344f430..0000000000000000000000000000000000000000 Binary files a/doc/workflow/rebase.png and /dev/null differ diff --git a/doc/workflow/release_branches.png b/doc/workflow/release_branches.png deleted file mode 100644 index da7ae53413a77246118b2cbb320b5707d4ee965e..0000000000000000000000000000000000000000 Binary files a/doc/workflow/release_branches.png and /dev/null differ diff --git a/doc/workflow/remove_checkbox.png b/doc/workflow/remove_checkbox.png deleted file mode 100644 index 3e247d381556a2f1f05ea8649105885d53174cd5..0000000000000000000000000000000000000000 Binary files a/doc/workflow/remove_checkbox.png and /dev/null differ diff --git a/doc/workflow/voting_slider.png b/doc/workflow/voting_slider.png deleted file mode 100644 index 4c660ef95937c66924a2f01373cc4efed4eae831..0000000000000000000000000000000000000000 Binary files a/doc/workflow/voting_slider.png and /dev/null differ diff --git a/doc/workflow/web_editor.md b/doc/workflow/web_editor.md deleted file mode 100644 index 7fc8f96b9ec6ab1af2bbee1b2e26f8e79d604c05..0000000000000000000000000000000000000000 --- a/doc/workflow/web_editor.md +++ /dev/null @@ -1,26 +0,0 @@ -# GitLab Web Editor - -In GitLab you can create new files and edit existing files using our web editor. -This is especially useful if you don't have access to a command line or you just want to do a quick fix. -You can easily access the web editor, depending on the context. -Let's start from newly created project. - -Click on `Add a file` -to create the first file and open it in the web editor. - -![web editor 1](web_editor/empty_project.png) - -Fill in a file name, some content, a commit message, branch name and press the commit button. -The file will be saved to the repository. - -![web editor 2](web_editor/new_file.png) - -You can edit any text file in a repository by pressing the edit button, when -viewing the file. - -![web editor 3](web_editor/show_file.png) - -Editing a file is almost the same as creating a new file, -with as addition the ability to preview your changes in a separate tab. Also you can save your change to another branch by filling out field `branch` - -![web editor 3](web_editor/edit_file.png) diff --git a/doc/workflow/web_editor/edit_file.png b/doc/workflow/web_editor/edit_file.png deleted file mode 100644 index f480c69ac3eafbbfd85b30ca0b1324d824f89409..0000000000000000000000000000000000000000 Binary files a/doc/workflow/web_editor/edit_file.png and /dev/null differ diff --git a/doc/workflow/web_editor/empty_project.png b/doc/workflow/web_editor/empty_project.png deleted file mode 100644 index 6a049f6beafbb1f449e43baa5925b10d31410cad..0000000000000000000000000000000000000000 Binary files a/doc/workflow/web_editor/empty_project.png and /dev/null differ diff --git a/doc/workflow/web_editor/new_file.png b/doc/workflow/web_editor/new_file.png deleted file mode 100644 index 55ebd9e025720ed108f16d5b6d61926701510c10..0000000000000000000000000000000000000000 Binary files a/doc/workflow/web_editor/new_file.png and /dev/null differ diff --git a/doc/workflow/web_editor/show_file.png b/doc/workflow/web_editor/show_file.png deleted file mode 100644 index 9cafcb551091a8959671dbedc113062ddbd7da7e..0000000000000000000000000000000000000000 Binary files a/doc/workflow/web_editor/show_file.png and /dev/null differ diff --git a/doc/workflow/workflow.md b/doc/workflow/workflow.md deleted file mode 100644 index f70e41df842faf1ae0c4b64d0fb3c2be92ce5ac2..0000000000000000000000000000000000000000 --- a/doc/workflow/workflow.md +++ /dev/null @@ -1,31 +0,0 @@ -# Feature branch workflow - -1. Clone project: - - ```bash - git clone git@example.com:project-name.git - ``` - -1. Create branch with your feature: - - ```bash - git checkout -b $feature_name - ``` - -1. Write code. Commit changes: - - ```bash - git commit -am "My feature is ready" - ``` - -1. Push your branch to GitLab: - - ```bash - git push origin $feature_name - ``` - -1. Review your code on commits page. - -1. Create a merge request. - -1. Your team lead will review the code & merge it to the main branch. diff --git a/docker/.dockerignore b/docker/.dockerignore deleted file mode 100644 index dd449725e188f816bcebfc05678064efcbc29a81..0000000000000000000000000000000000000000 --- a/docker/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -*.md diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index bb25bb677ca0cb7711bca26714b2527640ca9d89..0000000000000000000000000000000000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -FROM ubuntu:14.04 - -# Install required packages -RUN apt-get update -q \ - && DEBIAN_FRONTEND=noninteractive apt-get install -qy --no-install-recommends \ - ca-certificates \ - openssh-server \ - wget - -# Download & Install GitLab -# If the Omnibus package version below is outdated please contribute a merge request to update it. -# If you run GitLab Enterprise Edition point it to a location where you have downloaded it. -RUN TMP_FILE=$(mktemp); \ - wget -q -O $TMP_FILE https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.9.2-omnibus-1_amd64.deb \ - && dpkg -i $TMP_FILE \ - && rm -f $TMP_FILE - -# Manage SSHD through runit -RUN mkdir -p /opt/gitlab/sv/sshd/supervise \ - && mkfifo /opt/gitlab/sv/sshd/supervise/ok \ - && printf "#!/bin/sh\nexec 2>&1\numask 077\nexec /usr/sbin/sshd -D" > /opt/gitlab/sv/sshd/run \ - && chmod a+x /opt/gitlab/sv/sshd/run \ - && ln -s /opt/gitlab/sv/sshd /opt/gitlab/service \ - && mkdir -p /var/run/sshd - -# Expose web & ssh -EXPOSE 80 22 - -# Copy assets -COPY assets/wrapper /usr/local/bin/ - -# Wrapper to handle signal, trigger runit and reconfigure GitLab -CMD ["/usr/local/bin/wrapper"] diff --git a/docker/README.md b/docker/README.md deleted file mode 100644 index b7e8b0db7e75ba61872a1496e95e28250f1a54d7..0000000000000000000000000000000000000000 --- a/docker/README.md +++ /dev/null @@ -1,88 +0,0 @@ -What is GitLab? -=============== - -GitLab offers git repository management, code reviews, issue tracking, activity feeds, wikis. It has LDAP/AD integration, handles 25,000 users on a single server but can also run on a highly available active/active cluster. A subscription gives you access to our support team and to GitLab Enterprise Edition that contains extra features aimed at larger organizations. - - - -![GitLab Logo](https://gitlab.com/uploads/appearance/logo/1/brand_logo-c37eb221b456bb4b472cc1084480991f.png) - - -How to use these images -====================== - -At this moment GitLab doesn't have official Docker images. For convinience we will use suffix _xy where xy is current version of GitLab. -Build your own based on the Omnibus packages with the following commands (it assumes you're in the GitLab repo root directory): - -```bash -sudo docker build --tag gitlab_data_image docker/data/ -sudo docker build --tag gitlab_app_image_xy docker/ -``` - -We assume using a data volume container, this will simplify migrations and backups. -This empty container will exist to persist as volumes the 3 directories used by GitLab, so remember not to delete it. - -The directories on data container are: - -- `/var/opt/gitlab` for application data -- `/var/log/gitlab` for logs -- `/etc/gitlab` for configuration - -Create the data container with: - -```bash -sudo docker run --name gitlab_data gitlab_data_image /bin/true -``` - -After creating data container run GitLab container: - -```bash -sudo docker run --detach --name gitlab_app_xy --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data gitlab_app_image_xy -``` - -It might take a while before the docker container is responding to queries. You can follow the configuration process with `sudo docker logs -f gitlab_app_xy`. - -You can then go to `http://localhost:8080/` (or `http://192.168.59.103:8080/` if you use boot2docker). -You can login with username `root` and password `5iveL!fe`. -Next time, you can just use `sudo docker start gitlab_app` and `sudo docker stop gitlab_app`. - - -How to configure GitLab -======================== - -This container uses the official Omnibus GitLab distribution, so all configuration is done in the unique configuration file `/etc/gitlab/gitlab.rb`. - -To access GitLab configuration, you can start an interactive command line in a new container using the shared data volume container, you will be able to browse the 3 directories and use your favorite text editor: - -```bash -sudo docker run -ti -e TERM=linux --rm --volumes-from gitlab_data ubuntu -vi /etc/gitlab/gitlab.rb -``` - -**Note** that GitLab will reconfigure itself **at each container start.** You will need to restart the container to reconfigure your GitLab. - -You can find all available options in [Omnibus GitLab documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#configuration). - -How to upgrade GitLab -======================== - -To updgrade GitLab to new versions, stop running container, create new docker image and container from that image. - -It Assumes that you're upgrading from 7.8 to 7.9 and you're in the updated GitLab repo root directory: - -```bash -sudo docker stop gitlab_app_78 -sudo docker build --tag gitlab_app_image_79 docker/ -sudo docker run --detach --name gitlab_app_79 --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data gitlab_app_image_79 -``` - -On the first run GitLab will reconfigure and update itself. If everything runs OK don't forget to cleanup old container and image: - -```bash -sudo docker rm gitlab_app_78 -sudo docker rmi gitlab_app_image_78 -``` - -Troubleshooting -========================= -Please see the [troubleshooting](troubleshooting.md) file in this directory. diff --git a/docker/assets/wrapper b/docker/assets/wrapper deleted file mode 100755 index 9e6e7a05903021813c6c629df7864dc7ca63531c..0000000000000000000000000000000000000000 --- a/docker/assets/wrapper +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -function sigterm_handler() { - echo "SIGTERM signal received, try to gracefully shutdown all services..." - gitlab-ctl stop -} - -trap "sigterm_handler; exit" TERM - -function entrypoint() { - # Default is to run runit and reconfigure GitLab - gitlab-ctl reconfigure & - /opt/gitlab/embedded/bin/runsvdir-start & - wait -} - -entrypoint diff --git a/docker/data/Dockerfile b/docker/data/Dockerfile deleted file mode 100644 index ea0175c4aa2a6fabc335eee3566ff5521f444f08..0000000000000000000000000000000000000000 --- a/docker/data/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM busybox - -# Declare volumes -VOLUME ["/var/opt/gitlab", "/var/log/gitlab", "/etc/gitlab"] -# Copy assets -COPY assets/gitlab.rb /etc/gitlab/ - -CMD /bin/sh diff --git a/docker/data/assets/gitlab.rb b/docker/data/assets/gitlab.rb deleted file mode 100644 index 7fddf309c01e6bb8420386bfe2db485ba24990d0..0000000000000000000000000000000000000000 --- a/docker/data/assets/gitlab.rb +++ /dev/null @@ -1,37 +0,0 @@ -# External URL should be your Docker instance. -# By default, this example is the "standard" boot2docker IP. -# Always use port 80 here to force the internal nginx to bind port 80, -# even if you intend to use another port in Docker. -external_url "http://192.168.59.103/" - -# Prevent Postgres from trying to allocate 25% of total memory -postgresql['shared_buffers'] = '1MB' - -# Configure GitLab to redirect PostgreSQL logs to the data volume -postgresql['log_directory'] = '/var/log/gitlab/postgresql' - -# Some configuration of GitLab -# You can find more at https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#configuration -gitlab_rails['gitlab_email_from'] = 'gitlab@example.com' -gitlab_rails['gitlab_support_email'] = 'support@example.com' -gitlab_rails['time_zone'] = 'Europe/Paris' - -# SMTP settings -# You must use an external server, the Docker container does not install an SMTP server -gitlab_rails['smtp_enable'] = true -gitlab_rails['smtp_address'] = "smtp.example.com" -gitlab_rails['smtp_port'] = 587 -gitlab_rails['smtp_user_name'] = "user" -gitlab_rails['smtp_password'] = "password" -gitlab_rails['smtp_domain'] = "example.com" -gitlab_rails['smtp_authentication'] = "plain" -gitlab_rails['smtp_enable_starttls_auto'] = true - -# Enable LDAP authentication -# gitlab_rails['ldap_enabled'] = true -# gitlab_rails['ldap_host'] = 'ldap.example.com' -# gitlab_rails['ldap_port'] = 389 -# gitlab_rails['ldap_method'] = 'plain' # 'ssl' or 'plain' -# gitlab_rails['ldap_allow_username_or_email_login'] = false -# gitlab_rails['ldap_uid'] = 'uid' -# gitlab_rails['ldap_base'] = 'ou=users,dc=example,dc=com' diff --git a/docker/troubleshooting.md b/docker/troubleshooting.md deleted file mode 100644 index b1b70de5997aff463cdd8595f9e83d165d0739ca..0000000000000000000000000000000000000000 --- a/docker/troubleshooting.md +++ /dev/null @@ -1,63 +0,0 @@ -# Troubleshooting - -This is to troubleshoot https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/245 -But it might contain useful commands for other cases as well. - -The configuration to add the postgres log in vim is: -postgresql['log_directory'] = '/var/log/gitlab/postgresql' - -# Commands - -```bash -sudo docker build --tag gitlab_image docker/ - -sudo docker rm -f gitlab_app -sudo docker rm -f gitlab_data - -sudo docker run --name gitlab_data gitlab_image /bin/true - -sudo docker run -ti --rm --volumes-from gitlab_data ubuntu apt-get update && sudo apt-get install -y vim && sudo vim /etc/gitlab/gitlab.rb - -sudo docker run --detach --name gitlab_app --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data gitlab_image - -sudo docker run -t --rm --volumes-from gitlab_data ubuntu tail -f /var/log/gitlab/reconfigure.log - -sudo docker run -t --rm --volumes-from gitlab_data ubuntu tail -f /var/log/gitlab/postgresql/current - -sudo docker run -t --rm --volumes-from gitlab_data ubuntu cat /var/opt/gitlab/postgresql/data/postgresql.conf | grep shared_buffers - -sudo docker run -t --rm --volumes-from gitlab_data ubuntu cat /etc/gitlab/gitlab.rb -``` - -# Interactively - -```bash -# First start a GitLab container without starting GitLab -# This is almost the same as starting the GitLab container except: -# - we run interactively (-t -i) -# - we define TERM=linux because it allows to use arrow keys in vi (!!!) -# - we choose another startup command (bash) -sudo docker run -ti -e TERM=linux --name gitlab_app --publish 8080:80 --publish 2222:22 --volumes-from gitlab_data gitlab_image bash - -# Configure GitLab to redirect PostgreSQL logs -echo "postgresql['log_directory'] = '/var/log/gitlab/postgresql'" >> /etc/gitlab/gitlab.rb - -# Prevent Postgres from allocating 25% of total memory -echo "postgresql['shared_buffers'] = '1MB'" >> /etc/gitlab/gitlab.rb - -# You can now start GitLab manually from Bash (in the background) -# Maybe the command below is still missing something to run in the background -gitlab-ctl reconfigure > /var/log/gitlab/reconfigure.log & /opt/gitlab/embedded/bin/runsvdir-start & - -# Inspect PostgreSQL config -cat /var/opt/gitlab/postgresql/data/postgresql.conf | grep shared_buffers - -# And tail the logs (PostgreSQL log may not exist immediately) -tail -f /var/log/gitlab/reconfigure.log /var/log/gitlab/postgresql/current - -# And get the memory -cat /proc/meminfo -head /proc/sys/kernel/shmmax /proc/sys/kernel/shmall -free -m - -``` diff --git a/features/admin/active_tab.feature b/features/admin/active_tab.feature deleted file mode 100644 index 5de07e90e28482d45e680d51144c5ed3b48d3cdc..0000000000000000000000000000000000000000 --- a/features/admin/active_tab.feature +++ /dev/null @@ -1,44 +0,0 @@ -@admin -Feature: Admin Active Tab - Background: - Given I sign in as an admin - - Scenario: On Admin Home - Given I visit admin page - Then the active main tab should be Home - And no other main tabs should be active - - Scenario: On Admin Projects - Given I visit admin projects page - Then the active main tab should be Projects - And no other main tabs should be active - - Scenario: On Admin Groups - Given I visit admin groups page - Then the active main tab should be Groups - And no other main tabs should be active - - Scenario: On Admin Users - Given I visit admin users page - Then the active main tab should be Users - And no other main tabs should be active - - Scenario: On Admin Logs - Given I visit admin logs page - Then the active main tab should be Logs - And no other main tabs should be active - - Scenario: On Admin Messages - Given I visit admin messages page - Then the active main tab should be Messages - And no other main tabs should be active - - Scenario: On Admin Hooks - Given I visit admin hooks page - Then the active main tab should be Hooks - And no other main tabs should be active - - Scenario: On Admin Resque - Given I visit admin Resque page - Then the active main tab should be Resque - And no other main tabs should be active diff --git a/features/admin/applications.feature b/features/admin/applications.feature deleted file mode 100644 index 2a00e1666c01239e7c44dc1bd40e2a0344124955..0000000000000000000000000000000000000000 --- a/features/admin/applications.feature +++ /dev/null @@ -1,18 +0,0 @@ -@admin -Feature: Admin Applications - Background: - Given I sign in as an admin - And I visit applications page - - Scenario: I can manage application - Then I click on new application button - And I should see application form - Then I fill application form out and submit - And I see application - Then I click edit - And I see edit application form - Then I change name of application and submit - And I see that application was changed - Then I visit applications page - And I click to remove application - Then I see that application is removed \ No newline at end of file diff --git a/features/admin/broadcast_messages.feature b/features/admin/broadcast_messages.feature deleted file mode 100644 index b2c3112320ad2bc81c434ccd717250f83e7f2bd8..0000000000000000000000000000000000000000 --- a/features/admin/broadcast_messages.feature +++ /dev/null @@ -1,21 +0,0 @@ -@admin -Feature: Admin Broadcast Messages - Background: - Given I sign in as an admin - And application already has admin messages - And I visit admin messages page - - Scenario: See broadcast messages list - Then I should be all broadcast messages - - Scenario: Create a broadcast message - When submit form with new broadcast message - Then I should be redirected to admin messages page - And I should see newly created broadcast message - - Scenario: Create a customized broadcast message - When submit form with new customized broadcast message - Then I should be redirected to admin messages page - And I should see newly created broadcast message - Then I visit dashboard page - And I should see a customized broadcast message diff --git a/features/admin/deploy_keys.feature b/features/admin/deploy_keys.feature deleted file mode 100644 index 9df47eb51fd0ed73d29917ee0b77d5d72d00cd16..0000000000000000000000000000000000000000 --- a/features/admin/deploy_keys.feature +++ /dev/null @@ -1,21 +0,0 @@ -@admin -Feature: Admin Deploy Keys - Background: - Given I sign in as an admin - And there are public deploy keys in system - - Scenario: Deploy Keys list - When I visit admin deploy keys page - Then I should see all public deploy keys - - Scenario: Deploy Keys show - When I visit admin deploy keys page - And I click on first deploy key - Then I should see deploy key details - - Scenario: Deploy Keys new - When I visit admin deploy keys page - And I click 'New Deploy Key' - And I submit new deploy key - Then I should be on admin deploy keys page - And I should see newly created deploy key diff --git a/features/admin/groups.feature b/features/admin/groups.feature deleted file mode 100644 index aa365a6ea1ab14f3115545ada55d0c655376ffd7..0000000000000000000000000000000000000000 --- a/features/admin/groups.feature +++ /dev/null @@ -1,29 +0,0 @@ -@admin -Feature: Admin Groups - Background: - Given I sign in as an admin - And I have group with projects - And User "John Doe" exists - And I visit admin groups page - - Scenario: See group list - Then I should be all groups - - Scenario: Create a group - When I click new group link - And submit form with new group info - Then I should be redirected to group page - And I should see newly created group - - @javascript - Scenario: Add user into projects in group - When I visit admin group page - When I select user "John Doe" from user list as "Reporter" - Then I should see "John Doe" in team list in every project as "Reporter" - - @javascript - Scenario: Remove user from group - Given we have user "John Doe" in group - When I visit admin group page - And I remove user "John Doe" from group - Then I should not see "John Doe" in team list diff --git a/features/admin/logs.feature b/features/admin/logs.feature deleted file mode 100644 index ceb3bc34927a9939fcc1b01adbd6d1e191571cb3..0000000000000000000000000000000000000000 --- a/features/admin/logs.feature +++ /dev/null @@ -1,8 +0,0 @@ -@admin -Feature: Admin Logs - Background: - Given I sign in as an admin - - Scenario: On Admin Logs - Given I visit admin logs page - Then I should see tabs with available logs diff --git a/features/admin/projects.feature b/features/admin/projects.feature deleted file mode 100644 index a6c3d6b78222b87b45503faa33cbb82ea186e967..0000000000000000000000000000000000000000 --- a/features/admin/projects.feature +++ /dev/null @@ -1,20 +0,0 @@ -@admin -Feature: Admin Projects - Background: - Given I sign in as an admin - And there are projects in system - - Scenario: Projects list - When I visit admin projects page - Then I should see all projects - - Scenario: Projects show - When I visit admin projects page - And I click on first project - Then I should see project details - - Scenario: Transfer project - Given group 'Web' - And I visit admin project page - When I transfer project to group 'Web' - Then I should see project transfered diff --git a/features/admin/settings.feature b/features/admin/settings.feature deleted file mode 100644 index 52e47307b23494f57c351161b0730a0b29de68e3..0000000000000000000000000000000000000000 --- a/features/admin/settings.feature +++ /dev/null @@ -1,16 +0,0 @@ -@admin -Feature: Admin Settings - Background: - Given I sign in as an admin - And I visit admin settings page - - Scenario: Change application settings - When I modify settings and save form - Then I should see application settings saved - - Scenario: Change Slack Service Template settings - When I click on "Service Templates" - And I click on "Slack" service - Then I check all events and submit form - And I should see service template settings saved - And I should see all checkboxes checked diff --git a/features/admin/users.feature b/features/admin/users.feature deleted file mode 100644 index 1a8720dd77edfb081a99badfc4b3e047e6baa19e..0000000000000000000000000000000000000000 --- a/features/admin/users.feature +++ /dev/null @@ -1,47 +0,0 @@ -@admin -Feature: Admin Users - Background: - Given I sign in as an admin - And system has users - - Scenario: On Admin Users - Given I visit admin users page - Then I should see all users - - Scenario: Edit user and change username to non ascii char - When I visit admin users page - And Click edit - And Input non ascii char in username - And Click save - Then See username error message - And Not changed form action url - - Scenario: Show user attributes - Given user "Mike" with groups and projects - Given I visit admin users page - And click on "Mike" link - Then I should see user "Mike" details - - Scenario: Edit my user attributes - Given I visit admin users page - And click edit on my user - When I submit modified user - Then I see user attributes changed - -@javascript - Scenario: Remove users secondary email - Given I visit admin users page - And I view the user with secondary email - And I see the secondary email - When I click remove secondary email - Then I should not see secondary email anymore - - Scenario: Show user keys - Given user "Pete" with ssh keys - And I visit admin users page - And click on user "Pete" - Then I should see key list - And I click on the key title - Then I should see key details - And I click on remove key - Then I should see the key removed diff --git a/features/dashboard/active_tab.feature b/features/dashboard/active_tab.feature deleted file mode 100644 index 08b87808f337eac54d8b70809af9b78a532b5f5b..0000000000000000000000000000000000000000 --- a/features/dashboard/active_tab.feature +++ /dev/null @@ -1,24 +0,0 @@ -@dashboard -Feature: Dashboard Active Tab - Background: - Given I sign in as a user - - Scenario: On Dashboard Home - Given I visit dashboard page - Then the active main tab should be Home - And no other main tabs should be active - - Scenario: On Dashboard Issues - Given I visit dashboard issues page - Then the active main tab should be Issues - And no other main tabs should be active - - Scenario: On Dashboard Merge Requests - Given I visit dashboard merge requests page - Then the active main tab should be Merge Requests - And no other main tabs should be active - - Scenario: On Dashboard Help - Given I visit dashboard help page - Then the active main tab should be Help - And no other main tabs should be active diff --git a/features/dashboard/archived_projects.feature b/features/dashboard/archived_projects.feature deleted file mode 100644 index 69b3a7764419da1d477afb7019c2a55b62bae350..0000000000000000000000000000000000000000 --- a/features/dashboard/archived_projects.feature +++ /dev/null @@ -1,12 +0,0 @@ -@dashboard -Feature: Dashboard Archived Projects - Background: - Given I sign in as a user - And I own project "Shop" - And I own project "Forum" - And project "Forum" is archived - And I visit dashboard page - - Scenario: I should see non-archived projects on dashboard - Then I should see "Shop" project link - And I should not see "Forum" project link diff --git a/features/dashboard/dashboard.feature b/features/dashboard/dashboard.feature deleted file mode 100644 index 1959d3270823f22209e0db4f15afada303362343..0000000000000000000000000000000000000000 --- a/features/dashboard/dashboard.feature +++ /dev/null @@ -1,37 +0,0 @@ -@dashboard -Feature: Dashboard - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has push event - And I visit dashboard page - - @javascript - Scenario: I should see projects list - Then I should see "New Project" link - Then I should see "Shop" project link - Then I should see project "Shop" activity feed - - Scenario: I should see groups list - Given I have group with projects - And I visit dashboard page - Then I should see groups list - - @javascript - Scenario: I should see last push widget - Then I should see last push widget - And I click "Create Merge Request" link - Then I see prefilled new Merge Request page - - @javascript - Scenario: I should see User joined Project event - Given user with name "John Doe" joined project "Shop" - When I visit dashboard page - Then I should see "John Doe joined project Shop" event - - @javascript - Scenario: I should see User left Project event - Given user with name "John Doe" joined project "Shop" - And user with name "John Doe" left project "Shop" - When I visit dashboard page - Then I should see "John Doe left project Shop" event diff --git a/features/dashboard/event_filters.feature b/features/dashboard/event_filters.feature deleted file mode 100644 index ec5680caba68c0726eea82b09f97645eddc081ef..0000000000000000000000000000000000000000 --- a/features/dashboard/event_filters.feature +++ /dev/null @@ -1,52 +0,0 @@ -@dashboard -Feature: Event Filters - Background: - Given I sign in as a user - And I own a project - And this project has push event - And this project has new member event - And this project has merge request event - And I visit dashboard page - - @javascript - Scenario: I should see all events - Then I should see push event - And I should see new member event - And I should see merge request event - - @javascript - Scenario: I should see only pushed events - When I click "push" event filter - Then I should see push event - And I should not see new member event - And I should not see merge request event - - @javascript - Scenario: I should see only joined events - When I click "team" event filter - Then I should see new member event - And I should not see push event - And I should not see merge request event - - @javascript - Scenario: I should see only merged events - When I click "merge" event filter - Then I should see merge request event - And I should not see push event - And I should not see new member event - - @javascript - Scenario: I should see only selected events while page reloaded - When I click "push" event filter - And I visit dashboard page - Then I should see push event - And I should not see new member event - When I click "team" event filter - And I visit dashboard page - Then I should see push event - And I should see new member event - And I should not see merge request event - When I click "push" event filter - Then I should not see push event - And I should see new member event - And I should not see merge request event diff --git a/features/dashboard/group.feature b/features/dashboard/group.feature deleted file mode 100644 index cf4b8d7283b3c796fe1099884ec90aae9a290c69..0000000000000000000000000000000000000000 --- a/features/dashboard/group.feature +++ /dev/null @@ -1,56 +0,0 @@ -@dashboard -Feature: Dashboard Group - Background: - Given I sign in as "John Doe" - And "John Doe" is owner of group "Owned" - And "John Doe" is guest of group "Guest" - - # Leave groups - - @javascript - Scenario: Owner should be able to leave from group if he is not the last owner - Given "Mary Jane" is owner of group "Owned" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should see group "Guest" in group list - When I click on the "Leave" button for group "Owned" - And I visit dashboard groups page - Then I should not see group "Owned" in group list - Then I should see group "Guest" in group list - - @javascript - Scenario: Owner should not be able to leave from group if he is the last owner - Given "Mary Jane" is guest of group "Owned" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should see group "Guest" in group list - Then I should not see the "Leave" button for group "Owned" - - @javascript - Scenario: Guest should be able to leave from group - Given "Mary Jane" is guest of group "Guest" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should see group "Guest" in group list - When I click on the "Leave" button for group "Guest" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should not see group "Guest" in group list - - @javascript - Scenario: Guest should be able to leave from group even if he is the only user in the group - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should see group "Guest" in group list - When I click on the "Leave" button for group "Guest" - When I visit dashboard groups page - Then I should see group "Owned" in group list - Then I should not see group "Guest" in group list - - Scenario: Create a group from dasboard - And I visit dashboard groups page - And I click new group link - And submit form with new group "Samurai" info - Then I should be redirected to group "Samurai" page - And I should see newly created group "Samurai" - diff --git a/features/dashboard/help.feature b/features/dashboard/help.feature deleted file mode 100644 index bca2772897b0a78722834360da8323ecc978777d..0000000000000000000000000000000000000000 --- a/features/dashboard/help.feature +++ /dev/null @@ -1,9 +0,0 @@ -@dashboard -Feature: Dashboard Help - Background: - Given I sign in as a user - And I visit the "Rake Tasks" help page - - Scenario: The markdown should be rendered correctly - Then I should see "Rake Tasks" page markdown rendered - And Header "Rebuild project satellites" should have correct ids and links diff --git a/features/dashboard/issues.feature b/features/dashboard/issues.feature deleted file mode 100644 index 99dad88a40289274f1c4fd5da5d8066f8d6e002a..0000000000000000000000000000000000000000 --- a/features/dashboard/issues.feature +++ /dev/null @@ -1,21 +0,0 @@ -@dashboard -Feature: Dashboard Issues - Background: - Given I sign in as a user - And I have authored issues - And I have assigned issues - And I have other issues - And I visit dashboard issues page - - Scenario: I should see assigned issues - Then I should see issues assigned to me - - @javascript - Scenario: I should see authored issues - When I click "Authored by me" link - Then I should see issues authored by me - - @javascript - Scenario: I should see all issues - When I click "All" link - Then I should see all issues diff --git a/features/dashboard/merge_requests.feature b/features/dashboard/merge_requests.feature deleted file mode 100644 index 4a2c997d707f7dfae6877a3bec2fd94e2eb0df96..0000000000000000000000000000000000000000 --- a/features/dashboard/merge_requests.feature +++ /dev/null @@ -1,21 +0,0 @@ -@dashboard -Feature: Dashboard Merge Requests - Background: - Given I sign in as a user - And I have authored merge requests - And I have assigned merge requests - And I have other merge requests - And I visit dashboard merge requests page - - Scenario: I should see assigned merge_requests - Then I should see merge requests assigned to me - - @javascript - Scenario: I should see authored merge_requests - When I click "Authored by me" link - Then I should see merge requests authored by me - - @javascript - Scenario: I should see all merge_requests - When I click "All" link - Then I should see all merge requests diff --git a/features/dashboard/new_project.feature b/features/dashboard/new_project.feature deleted file mode 100644 index 431dc4ccfcb258c50a042274bb53d40832049b3b..0000000000000000000000000000000000000000 --- a/features/dashboard/new_project.feature +++ /dev/null @@ -1,13 +0,0 @@ -@dashboard -Feature: New Project -Background: - Given I sign in as a user - And I own project "Shop" - And I visit dashboard page - - @javascript - Scenario: I should see New projects page - Given I click "New project" link - Then I see "New project" page - When I click on "Import project from GitHub" - Then I see instructions on how to import from GitHub diff --git a/features/dashboard/shortcuts.feature b/features/dashboard/shortcuts.feature deleted file mode 100644 index 41d79aa6ec86d454736ebb682eddf66368380f13..0000000000000000000000000000000000000000 --- a/features/dashboard/shortcuts.feature +++ /dev/null @@ -1,21 +0,0 @@ -@dashboard -Feature: Dashboard Shortcuts - Background: - Given I sign in as a user - And I visit dashboard page - - @javascript - Scenario: Navigate to projects tab - Given I press "g" and "p" - Then the active main tab should be Projects - - @javascript - Scenario: Navigate to issue tab - Given I press "g" and "i" - Then the active main tab should be Issues - - @javascript - Scenario: Navigate to merge requests tab - Given I press "g" and "m" - Then the active main tab should be Merge Requests - diff --git a/features/dashboard/starred_projects.feature b/features/dashboard/starred_projects.feature deleted file mode 100644 index 9dfd2fbab9cb2a43e3364f25ccd22b5185259d20..0000000000000000000000000000000000000000 --- a/features/dashboard/starred_projects.feature +++ /dev/null @@ -1,12 +0,0 @@ -@dashboard -Feature: Dashboard Starred Projects - Background: - Given I sign in as a user - And public project "Community" - And I starred project "Community" - And I own project "Shop" - And I visit dashboard starred projects page - - Scenario: I should see projects list - Then I should see project "Community" - And I should not see project "Shop" diff --git a/features/explore/groups.feature b/features/explore/groups.feature deleted file mode 100644 index c11634bd74a800b23d145995768c2bc48c97c50d..0000000000000000000000000000000000000000 --- a/features/explore/groups.feature +++ /dev/null @@ -1,147 +0,0 @@ -@public -Feature: Explore Groups - Background: - Given group "TestGroup" has private project "Enterprise" - - Scenario: I should not see group with private projects as visitor - When I visit group "TestGroup" page - Then I should be redirected to sign in page - - Scenario: I should not see group with private projects group as user - When I sign in as a user - And I visit group "TestGroup" page - Then page status code should be 404 - - Scenario: I should not see group with private and internal projects as visitor - Given group "TestGroup" has internal project "Internal" - When I visit group "TestGroup" page - Then I should be redirected to sign in page - - Scenario: I should see group with private and internal projects as user - Given group "TestGroup" has internal project "Internal" - When I sign in as a user - And I visit group "TestGroup" page - Then I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group issues for internal project as user - Given group "TestGroup" has internal project "Internal" - When I sign in as a user - And I visit group "TestGroup" issues page - Then I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group merge requests for internal project as user - Given group "TestGroup" has internal project "Internal" - When I sign in as a user - And I visit group "TestGroup" merge requests page - Then I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group's members as user - Given group "TestGroup" has internal project "Internal" - And "John Doe" is owner of group "TestGroup" - When I sign in as a user - And I visit group "TestGroup" members page - Then I should see group member "John Doe" - And I should not see member roles - - Scenario: I should see group with private, internal and public projects as visitor - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I visit group "TestGroup" page - Then I should see project "Community" items - And I should not see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group issues for public project as visitor - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I visit group "TestGroup" issues page - Then I should see project "Community" items - And I should not see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group merge requests for public project as visitor - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I visit group "TestGroup" merge requests page - Then I should see project "Community" items - And I should not see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group's members as visitor - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - And "John Doe" is owner of group "TestGroup" - When I visit group "TestGroup" members page - Then I should see group member "John Doe" - And I should not see member roles - - Scenario: I should see group with private, internal and public projects as user - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I sign in as a user - And I visit group "TestGroup" page - Then I should see project "Community" items - And I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group issues for internal and public projects as user - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I sign in as a user - And I visit group "TestGroup" issues page - Then I should see project "Community" items - And I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group merge requests for internal and public projects as user - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - When I sign in as a user - And I visit group "TestGroup" merge requests page - Then I should see project "Community" items - And I should see project "Internal" items - And I should not see project "Enterprise" items - - Scenario: I should see group's members as user - Given group "TestGroup" has internal project "Internal" - Given group "TestGroup" has public project "Community" - And "John Doe" is owner of group "TestGroup" - When I sign in as a user - And I visit group "TestGroup" members page - Then I should see group member "John Doe" - And I should not see member roles - - Scenario: I should see group with public project in public groups area - Given group "TestGroup" has public project "Community" - When I visit the public groups area - Then I should see group "TestGroup" - - Scenario: I should not see group with internal project in public groups area - Given group "TestGroup" has internal project "Internal" - When I visit the public groups area - Then I should not see group "TestGroup" - - Scenario: I should not see group with private project in public groups area - When I visit the public groups area - Then I should not see group "TestGroup" - - Scenario: I should see group with public project in public groups area as user - Given group "TestGroup" has public project "Community" - When I sign in as a user - And I visit the public groups area - Then I should see group "TestGroup" - - Scenario: I should see group with internal project in public groups area as user - Given group "TestGroup" has internal project "Internal" - When I sign in as a user - And I visit the public groups area - Then I should see group "TestGroup" - - Scenario: I should not see group with private project in public groups area as user - When I sign in as a user - And I visit the public groups area - Then I should not see group "TestGroup" - diff --git a/features/explore/projects.feature b/features/explore/projects.feature deleted file mode 100644 index a1b2972267871f314fb427560d9d4038ab2e7476..0000000000000000000000000000000000000000 --- a/features/explore/projects.feature +++ /dev/null @@ -1,116 +0,0 @@ -@public -Feature: Explore Projects - Background: - Given public project "Community" - And internal project "Internal" - And private project "Enterprise" - - Scenario: I visit public area - When I visit the public projects area - Then I should see project "Community" - And I should not see project "Internal" - And I should not see project "Enterprise" - - Scenario: I visit public project page - When I visit project "Community" page - Then I should see project "Community" home page - - Scenario: I visit internal project page - When I visit project "Internal" page - Then I should be redirected to sign in page - - Scenario: I visit private project page - When I visit project "Enterprise" page - Then I should be redirected to sign in page - - Scenario: I visit an empty public project page - Given public empty project "Empty Public Project" - When I visit empty project page - Then I should see empty public project details - And I should see empty public project details with http clone info - - Scenario: I visit an empty public project page as user - Given I sign in as a user - And public empty project "Empty Public Project" - When I visit empty project page - Then I should see empty public project details - And I should see empty public project details with ssh clone info - - Scenario: I visit public area as user - Given I sign in as a user - When I visit the public projects area - Then I should see project "Community" - And I should see project "Internal" - And I should not see project "Enterprise" - - Scenario: I visit internal project page as user - Given I sign in as a user - When I visit project "Internal" page - Then I should see project "Internal" home page - - Scenario: I visit public project page - When I visit project "Community" page - Then I should see project "Community" home page - And I should see an http link to the repository - - Scenario: I visit public project page as user - Given I sign in as a user - When I visit project "Community" page - Then I should see project "Community" home page - And I should see an ssh link to the repository - - Scenario: I visit an empty public project page - Given public empty project "Empty Public Project" - When I visit empty project page - Then I should see empty public project details - - Scenario: I visit public project issues page as a non authorized user - Given I visit project "Community" page - And I visit "Community" issues page - Then I should see list of issues for "Community" project - - Scenario: I visit public project issues page as authorized user - Given I sign in as a user - Given I visit project "Community" page - And I visit "Community" issues page - Then I should see list of issues for "Community" project - - Scenario: I visit internal project issues page as authorized user - Given I sign in as a user - Given I visit project "Internal" page - And I visit "Internal" issues page - Then I should see list of issues for "Internal" project - - Scenario: I visit public project merge requests page as an authorized user - Given I sign in as a user - Given I visit project "Community" page - And I visit "Community" merge requests page - And project "Community" has "Bug fix" open merge request - Then I should see list of merge requests for "Community" project - - Scenario: I visit public project merge requests page as a non authorized user - Given I visit project "Community" page - And I visit "Community" merge requests page - And project "Community" has "Bug fix" open merge request - Then I should see list of merge requests for "Community" project - - Scenario: I visit internal project merge requests page as an authorized user - Given I sign in as a user - Given I visit project "Internal" page - And I visit "Internal" merge requests page - And project "Internal" has "Feature implemented" open merge request - Then I should see list of merge requests for "Internal" project - - Scenario: Trending page - Given I sign in as a user - And project "Community" has comments - When I visit the explore trending projects - Then I should see project "Community" - And I should not see project "Internal" - And I should not see project "Enterprise" - - Scenario: Most starred page - Given I sign in as a user - When I visit the explore starred projects - Then I should see project "Community" - And I should see project "Internal" diff --git a/features/groups.feature b/features/groups.feature deleted file mode 100644 index 415e43d6ae73b91c1821fe29aa8e41cf6441a59a..0000000000000000000000000000000000000000 --- a/features/groups.feature +++ /dev/null @@ -1,150 +0,0 @@ -Feature: Groups - Background: - Given I sign in as "John Doe" - And "John Doe" is owner of group "Owned" - And "John Doe" is guest of group "Guest" - - @javascript - Scenario: I should see group "Owned" dashboard list - When I visit group "Owned" page - Then I should see group "Owned" projects list - And I should see projects activity feed - - Scenario: I should see group "Owned" issues list - Given project from group "Owned" has issues assigned to me - When I visit group "Owned" issues page - Then I should see issues from group "Owned" assigned to me - - Scenario: I should see group "Owned" merge requests list - Given project from group "Owned" has merge requests assigned to me - When I visit group "Owned" merge requests page - Then I should see merge requests from group "Owned" assigned to me - - @javascript - Scenario: I should add user to projects in group "Owned" - Given User "Mary Jane" exists - When I visit group "Owned" members page - And I select user "Mary Jane" from list with role "Reporter" - Then I should see user "Mary Jane" in team list - - Scenario: I should see edit group "Owned" page - When I visit group "Owned" settings page - And I change group "Owned" name to "new-name" - Then I should see new group "Owned" name - - Scenario: I edit group "Owned" avatar - When I visit group "Owned" settings page - And I change group "Owned" avatar - And I visit group "Owned" settings page - Then I should see new group "Owned" avatar - And I should see the "Remove avatar" button - - Scenario: I remove group "Owned" avatar - When I visit group "Owned" settings page - And I have group "Owned" avatar - And I visit group "Owned" settings page - And I remove group "Owned" avatar - Then I should not see group "Owned" avatar - And I should not see the "Remove avatar" button - - @javascript - Scenario: Add user to group - Given gitlab user "Mike" - When I visit group "Owned" members page - And I click link "Add members" - When I select "Mike" as "Reporter" - Then I should see "Mike" in team list as "Reporter" - - @javascript - Scenario: Invite user to group - When I visit group "Owned" members page - And I click link "Add members" - When I select "sjobs@apple.com" as "Reporter" - Then I should see "sjobs@apple.com" in team list as invited "Reporter" - - # Leave - - @javascript - Scenario: Owner should be able to remove himself from group if he is not the last owner - Given "Mary Jane" is owner of group "Owned" - When I visit group "Owned" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - When I click on the "Remove User From Group" button for "John Doe" - And I visit group "Owned" members page - Then I should not see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - - @javascript - Scenario: Owner should not be able to remove himself from group if he is the last owner - Given "Mary Jane" is guest of group "Owned" - When I visit group "Owned" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - Then I should not see the "Remove User From Group" button for "John Doe" - - @javascript - Scenario: Guest should be able to remove himself from group - Given "Mary Jane" is guest of group "Guest" - When I visit group "Guest" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - When I click on the "Remove User From Group" button for "John Doe" - When I visit group "Guest" members page - Then I should not see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - - @javascript - Scenario: Guest should be able to remove himself from group even if he is the only user in the group - When I visit group "Guest" members page - Then I should see user "John Doe" in team list - When I click on the "Remove User From Group" button for "John Doe" - When I visit group "Guest" members page - Then I should not see user "John Doe" in team list - - # Remove others - - Scenario: Owner should be able to remove other users from group - Given "Mary Jane" is owner of group "Owned" - When I visit group "Owned" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - When I click on the "Remove User From Group" button for "Mary Jane" - When I visit group "Owned" members page - Then I should see user "John Doe" in team list - Then I should not see user "Mary Jane" in team list - - Scenario: Guest should not be able to remove other users from group - Given "Mary Jane" is guest of group "Guest" - When I visit group "Guest" members page - Then I should see user "John Doe" in team list - Then I should see user "Mary Jane" in team list - Then I should not see the "Remove User From Group" button for "Mary Jane" - - Scenario: Search member by name - Given "Mary Jane" is guest of group "Guest" - And I visit group "Guest" members page - When I search for 'Mary' member - Then I should see user "Mary Jane" in team list - Then I should not see user "John Doe" in team list - - # Group milestones - - Scenario: I should see group "Owned" milestone index page with no milestones - When I visit group "Owned" page - And I click on group milestones - Then I should see group milestones index page has no milestones - - Scenario: I should see group "Owned" milestone index page with milestones - Given Group has projects with milestones - When I visit group "Owned" page - And I click on group milestones - Then I should see group milestones index page with milestones - - Scenario: I should see group "Owned" milestone show page - Given Group has projects with milestones - When I visit group "Owned" page - And I click on group milestones - And I click on one group milestone - Then I should see group milestone with descriptions and expiry date - And I should see group milestone with all issues and MRs assigned to that milestone diff --git a/features/invites.feature b/features/invites.feature deleted file mode 100644 index dc8eefaeaed5a5db1c2f35d4cfd4bd0539198005..0000000000000000000000000000000000000000 --- a/features/invites.feature +++ /dev/null @@ -1,45 +0,0 @@ -Feature: Invites - Background: - Given "John Doe" is owner of group "Owned" - And "John Doe" has invited "user@example.com" to group "Owned" - - Scenario: Viewing invitation when signed out - When I visit the invitation page - Then I should be redirected to the sign in page - And I should see a notice telling me to sign in - - Scenario: Signing in to view invitation - When I visit the invitation page - And I sign in as "Mary Jane" - Then I should be redirected to the invitation page - - Scenario: Viewing invitation when signed in - Given I sign in as "Mary Jane" - And I visit the invitation page - Then I should see the invitation details - And I should see an "Accept invitation" button - And I should see a "Decline" button - - Scenario: Viewing invitation as an existing member - Given I sign in as "John Doe" - And I visit the invitation page - Then I should see a message telling me I'm already a member - - Scenario: Accepting the invitation - Given I sign in as "Mary Jane" - And I visit the invitation page - And I click the "Accept invitation" button - Then I should be redirected to the group page - And I should see a notice telling me I have access - - Scenario: Declining the application when signed in - Given I sign in as "Mary Jane" - And I visit the invitation page - And I click the "Decline" button - Then I should be redirected to the dashboard - And I should see a notice telling me I have declined - - Scenario: Declining the application when signed out - When I visit the invitation's decline page - Then I should be redirected to the sign in page - And I should see a notice telling me I have declined diff --git a/features/profile/active_tab.feature b/features/profile/active_tab.feature deleted file mode 100644 index 7801ae5b8ca66d1f9c319399dea8820239b28e6a..0000000000000000000000000000000000000000 --- a/features/profile/active_tab.feature +++ /dev/null @@ -1,29 +0,0 @@ -@profile -Feature: Profile Active Tab - Background: - Given I sign in as a user - - Scenario: On Profile Home - Given I visit profile page - Then the active main tab should be Home - And no other main tabs should be active - - Scenario: On Profile Account - Given I visit profile account page - Then the active main tab should be Account - And no other main tabs should be active - - Scenario: On Profile SSH Keys - Given I visit profile SSH keys page - Then the active main tab should be SSH Keys - And no other main tabs should be active - - Scenario: On Profile Design - Given I visit profile design page - Then the active main tab should be Design - And no other main tabs should be active - - Scenario: On Profile History - Given I visit profile history page - Then the active main tab should be History - And no other main tabs should be active diff --git a/features/profile/emails.feature b/features/profile/emails.feature deleted file mode 100644 index 19ed949f6ae5d84a841d3614a890945e983e02b0..0000000000000000000000000000000000000000 --- a/features/profile/emails.feature +++ /dev/null @@ -1,26 +0,0 @@ -@profile -Feature: Profile Emails - Background: - Given I sign in as a user - And I visit profile emails page - - Scenario: I should see emails - Then I should see my emails - - Scenario: Add new email - Given I submit new email "my@email.com" - Then I should see new email "my@email.com" - And I should see my emails - - Scenario: Add duplicate email - Given I submit duplicate email @user.email - Then I should not have @user.email added - And I should see my emails - - Scenario: Remove email - Given I submit new email "my@email.com" - Then I should see new email "my@email.com" - And I should see my emails - Then I click link "Remove" for "my@email.com" - Then I should not see email "my@email.com" - And I should see my emails diff --git a/features/profile/notifications.feature b/features/profile/notifications.feature deleted file mode 100644 index 55997d44dec28477bba861b2788c1a893f5a9534..0000000000000000000000000000000000000000 --- a/features/profile/notifications.feature +++ /dev/null @@ -1,9 +0,0 @@ -@profile -Feature: Profile Notifications - Background: - Given I sign in as a user - And I own project "Shop" - - Scenario: I visit notifications tab - When I visit profile notifications page - Then I should see global notifications settings diff --git a/features/profile/profile.feature b/features/profile/profile.feature deleted file mode 100644 index d586167cdf5599e102226fe25e8bf9d826ea5fc8..0000000000000000000000000000000000000000 --- a/features/profile/profile.feature +++ /dev/null @@ -1,99 +0,0 @@ -@profile -Feature: Profile - Background: - Given I sign in as a user - - Scenario: I look at my profile - Given I visit profile page - Then I should see my profile info - - Scenario: I can see groups I belong to - Given I have group with projects - When I visit profile page - And I click on my profile picture - Then I should see my user page - And I should see groups I belong to - - Scenario: I edit profile - Given I visit profile page - Then I change my profile info - And I should see new profile info - - Scenario: I change my password without old one - Given I visit profile password page - When I try change my password w/o old one - Then I should see a missing password error message - And I should be redirected to password page - - Scenario: I change my password - Given I visit profile password page - Then I change my password - And I should be redirected to sign in page - - Scenario: I edit my avatar - Given I visit profile page - Then I change my avatar - And I should see new avatar - And I should see the "Remove avatar" button - - Scenario: I remove my avatar - Given I visit profile page - And I have an avatar - When I remove my avatar - Then I should see my gravatar - And I should not see the "Remove avatar" button - - Scenario: My password is expired - Given my password is expired - And I am not an ldap user - Given I visit profile password page - Then I redirected to expired password page - And I submit new password - And I redirected to sign in page - - Scenario: I unsuccessfully change my password - Given I visit profile password page - When I unsuccessfully change my password - Then I should see a password error message - - Scenario: I reset my token - Given I visit profile account page - Then I reset my token - And I should see new token - - Scenario: I visit history tab - Given I have activity - When I visit profile history page - Then I should see my activity - - Scenario: I visit my user page - When I visit profile page - And I click on my profile picture - Then I should see my user page - - Scenario: I can manage application - Given I visit profile applications page - Then I click on new application button - And I should see application form - Then I fill application form out and submit - And I see application - Then I click edit - And I see edit application form - Then I change name of application and submit - And I see that application was changed - Then I visit profile applications page - And I click to remove application - Then I see that application is removed - - @javascript - Scenario: I change my application theme - Given I visit profile design page - When I change my application theme - Then I should see the theme change immediately - And I should receive feedback that the changes were saved - - @javascript - Scenario: I change my code preview theme - Given I visit profile design page - When I change my code preview theme - Then I should receive feedback that the changes were saved diff --git a/features/profile/ssh_keys.feature b/features/profile/ssh_keys.feature deleted file mode 100644 index 581503fc5f9d9a00bf1ce8d02a0d1813f3980b08..0000000000000000000000000000000000000000 --- a/features/profile/ssh_keys.feature +++ /dev/null @@ -1,20 +0,0 @@ -@profile -Feature: Profile SSH Keys - Background: - Given I sign in as a user - And I have ssh key "ssh-rsa Work" - And I visit profile keys page - - Scenario: I should see ssh keys - Then I should see my ssh keys - - Scenario: Add new ssh key - Given I click link "Add new" - And I submit new ssh key "Laptop" - Then I should see new ssh key "Laptop" - - Scenario: Remove ssh key - Given I click link "Work" - And I click link "Remove" - Then I visit profile keys page - And I should not see "Work" ssh key diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature deleted file mode 100644 index 05faad4e645c79ea1bbad40874d34b54df2f7049..0000000000000000000000000000000000000000 --- a/features/project/active_tab.feature +++ /dev/null @@ -1,124 +0,0 @@ -Feature: Project Active Tab - Background: - Given I sign in as a user - And I own a project - - # Main Tabs - - Scenario: On Project Home - Given I visit my project's home page - Then the active main tab should be Home - And no other main tabs should be active - - Scenario: On Project Files - Given I visit my project's files page - Then the active main tab should be Files - And no other main tabs should be active - - Scenario: On Project Commits - Given I visit my project's commits page - Then the active main tab should be Commits - And no other main tabs should be active - - Scenario: On Project Network - Given I visit my project's network page - Then the active main tab should be Network - And no other main tabs should be active - - Scenario: On Project Issues - Given I visit my project's issues page - Then the active main tab should be Issues - And no other main tabs should be active - - Scenario: On Project Merge Requests - Given I visit my project's merge requests page - Then the active main tab should be Merge Requests - And no other main tabs should be active - - Scenario: On Project Wiki - Given I visit my project's wiki page - Then the active main tab should be Wiki - And no other main tabs should be active - - # Sub Tabs: Home - - Scenario: On Project Home/Show - Given I visit my project's home page - Then the active main tab should be Home - And no other main tabs should be active - - # Sub Tabs: Settings - - Scenario: On Project Settings/Team - Given I visit my project's settings page - And I click the "Team" tab - Then the active sub nav should be Team - And no other sub navs should be active - And the active main tab should be Settings - - Scenario: On Project Settings/Edit - Given I visit my project's settings page - And I click the "Edit" tab - Then the active sub nav should be Edit - And no other sub navs should be active - And the active main tab should be Settings - - Scenario: On Project Settings/Hooks - Given I visit my project's settings page - And I click the "Hooks" tab - Then the active sub nav should be Hooks - And no other sub navs should be active - And the active main tab should be Settings - - Scenario: On Project Settings/Deploy Keys - Given I visit my project's settings page - And I click the "Deploy Keys" tab - Then the active sub nav should be Deploy Keys - And no other sub navs should be active - And the active main tab should be Settings - - # Sub Tabs: Commits - - Scenario: On Project Commits/Commits - Given I visit my project's commits page - Then the active sub tab should be Commits - And no other sub tabs should be active - And the active main tab should be Commits - - Scenario: On Project Commits/Compare - Given I visit my project's commits page - And I click the "Compare" tab - Then the active sub tab should be Compare - And no other sub tabs should be active - And the active main tab should be Commits - - Scenario: On Project Commits/Branches - Given I visit my project's commits page - And I click the "Branches" tab - Then the active sub tab should be Branches - And no other sub tabs should be active - And the active main tab should be Commits - - Scenario: On Project Commits/Tags - Given I visit my project's commits page - And I click the "Tags" tab - Then the active sub tab should be Tags - And no other sub tabs should be active - And the active main tab should be Commits - - Scenario: On Project Issues/Browse - Given I visit my project's issues page - Then the active main tab should be Issues - And no other main tabs should be active - - Scenario: On Project Issues/Milestones - Given I visit my project's issues page - And I click the "Milestones" tab - Then the active main tab should be Milestones - And no other main tabs should be active - - Scenario: On Project Issues/Labels - Given I visit my project's issues page - And I click the "Labels" tab - Then the active main tab should be Labels - And no other main tabs should be active diff --git a/features/project/archived.feature b/features/project/archived.feature deleted file mode 100644 index ad466f4f3079613f81cdaabbdfe575339c5837cf..0000000000000000000000000000000000000000 --- a/features/project/archived.feature +++ /dev/null @@ -1,30 +0,0 @@ -Feature: Project Archived - Background: - Given I sign in as a user - And I own project "Shop" - And I own project "Forum" - - Scenario: I should not see archived on project page of not-archive project - And project "Forum" is archived - And I visit project "Shop" page - Then I should not see "Archived" - - Scenario: I should see archived on project page of archive project - And project "Forum" is archived - And I visit project "Forum" page - Then I should see "Archived" - - Scenario: I archive project - When project "Shop" has push event - And I visit project "Shop" page - And I visit edit project "Shop" page - And I set project archived - Then I should see "Archived" - - Scenario: I unarchive project - When project "Shop" has push event - And project "Shop" is archived - And I visit project "Shop" page - And I visit edit project "Shop" page - And I set project unarchived - Then I should not see "Archived" diff --git a/features/project/commits/branches.feature b/features/project/commits/branches.feature deleted file mode 100644 index 65d8e48b9b3978c7b4d88a38ed0ecb571b859ca5..0000000000000000000000000000000000000000 --- a/features/project/commits/branches.feature +++ /dev/null @@ -1,43 +0,0 @@ -Feature: Project Commits Branches - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has protected branches - - Scenario: I can see project all git branches - Given I visit project branches page - Then I should see "Shop" all branches list - - Scenario: I can see project protected git branches - Given I visit project protected branches page - Then I should see "Shop" protected branches list - - Scenario: I create a branch - Given I visit project branches page - And I click new branch link - And I submit new branch form - Then I should see new branch created - - @javascript - Scenario: I delete a branch - Given I visit project branches page - And I click branch 'improve/awesome' delete link - Then I should not see branch 'improve/awesome' - - Scenario: I create a branch with invalid name - Given I visit project branches page - And I click new branch link - And I submit new branch form with invalid name - Then I should see new an error that branch is invalid - - Scenario: I create a branch with invalid reference - Given I visit project branches page - And I click new branch link - And I submit new branch form with invalid reference - Then I should see new an error that ref is invalid - - Scenario: I create a branch that already exists - Given I visit project branches page - And I click new branch link - And I submit new branch form with branch that already exists - Then I should see new an error that branch already exists diff --git a/features/project/commits/comments.feature b/features/project/commits/comments.feature deleted file mode 100644 index c41075d7ad43fad991f2bbca8606017923299d33..0000000000000000000000000000000000000000 --- a/features/project/commits/comments.feature +++ /dev/null @@ -1,49 +0,0 @@ -Feature: Project Commits Comments - Background: - Given I sign in as a user - And I own project "Shop" - And I visit project commit page - - @javascript - Scenario: I can comment on a commit - Given I leave a comment like "XML attached" - Then I should see a comment saying "XML attached" - - @javascript - Scenario: I can't cancel the main form - Then I should not see the cancel comment button - - @javascript - Scenario: I can preview with text - Given I write a comment like ":+1: Nice" - Then The comment preview tab should be display rendered Markdown - - @javascript - Scenario: I preview a comment - Given I preview a comment text like "Bug fixed :smile:" - Then I should see the comment preview - And I should not see the comment text field - - @javascript - Scenario: I can edit after preview - Given I preview a comment text like "Bug fixed :smile:" - Then I should see the comment write tab - - @javascript - Scenario: I have a reset form after posting from preview - Given I preview a comment text like "Bug fixed :smile:" - And I submit the comment - Then I should see an empty comment text field - And I should not see the comment preview - - @javascript - Scenario: I can delete a comment - Given I leave a comment like "XML attached" - And I delete a comment - Then I should not see a comment saying "XML attached" - - @javascript - Scenario: I can edit a comment with +1 - Given I leave a comment like "XML attached" - And I edit the last comment with a +1 - Then I should see +1 in the description diff --git a/features/project/commits/commits.feature b/features/project/commits/commits.feature deleted file mode 100644 index c4b206edc95a30468157c41359e4687dbbd748df..0000000000000000000000000000000000000000 --- a/features/project/commits/commits.feature +++ /dev/null @@ -1,47 +0,0 @@ -Feature: Project Commits - Background: - Given I sign in as a user - And I own a project - And I visit my project's commits page - - Scenario: I browse commits list for master branch - Then I see project commits - - Scenario: I browse atom feed of commits list for master branch - Given I click atom feed link - Then I see commits atom feed - - Scenario: I browse commit from list - Given I click on commit link - Then I see commit info - And I see side-by-side diff button - - Scenario: I browse commit with side-by-side diff view - Given I click on commit link - And I click side-by-side diff button - Then I see inline diff button - - @javascript - Scenario: I compare refs - Given I visit compare refs page - And I fill compare fields with refs - Then I see compared refs - And I unfold diff - Then I should see additional file lines - - Scenario: I browse commits for a specific path - Given I visit my project's commits page for a specific path - Then I see breadcrumb links - - # TODO: Implement feature in graphs - #Scenario: I browse commits stats - #Given I visit my project's commits stats page - #Then I see commits stats - - Scenario: I browse big commit - Given I visit big commit page - Then I see big commit warning - - Scenario: I browse a commit with an image - Given I visit a commit with an image that changed - Then The diff links to both the previous and current image diff --git a/features/project/commits/diff_comments.feature b/features/project/commits/diff_comments.feature deleted file mode 100644 index 56b9a13678db530b00445b5eb19806b5d8bc7e29..0000000000000000000000000000000000000000 --- a/features/project/commits/diff_comments.feature +++ /dev/null @@ -1,79 +0,0 @@ -Feature: Project Commits Diff Comments - Background: - Given I sign in as a user - And I own project "Shop" - And I visit project commit page - - @javascript - Scenario: I can access add diff comment buttons - Then I should see add a diff comment button - - @javascript - Scenario: I can comment on a commit diff - Given I leave a diff comment like "Typo, please fix" - Then I should see a diff comment saying "Typo, please fix" - - @javascript - Scenario: I get a temporary form for the first comment on a diff line - Given I open a diff comment form - Then I should see a temporary diff comment form - - @javascript - Scenario: I have a cancel button on the diff form - Given I open a diff comment form - Then I should see the cancel comment button - - @javascript - Scenario: I can cancel a diff form - Given I open a diff comment form - And I cancel the diff comment - Then I should not see the diff comment form - - @javascript - Scenario: I can't open a second form for a diff line - Given I open a diff comment form - And I open a diff comment form - Then I should only see one diff form - - @javascript - Scenario: I can have multiple forms - Given I open a diff comment form - And I write a diff comment like ":-1: I don't like this" - And I open another diff comment form - Then I should see a diff comment form with ":-1: I don't like this" - And I should see an empty diff comment form - - @javascript - Scenario: I can preview multiple forms separately - Given I preview a diff comment text like "Should fix it :smile:" - And I preview another diff comment text like "DRY this up" - Then I should see two separate previews - - @javascript - Scenario: I have a reply button in discussions - Given I leave a diff comment like "Typo, please fix" - Then I should see a discussion reply button - - @javascript - Scenario: I can preview with text - Given I open a diff comment form - And I write a diff comment like ":-1: I don't like this" - Then The diff comment preview tab should display rendered Markdown - - @javascript - Scenario: I preview a diff comment - Given I preview a diff comment text like "Should fix it :smile:" - Then I should see the diff comment preview - And I should not see the diff comment text field - - @javascript - Scenario: I can edit after preview - Given I preview a diff comment text like "Should fix it :smile:" - Then I should see the diff comment write tab - - @javascript - Scenario: The form gets removed after posting - Given I preview a diff comment text like "Should fix it :smile:" - And I submit the diff comment - Then I should not see the diff comment form - And I should see a discussion reply button diff --git a/features/project/commits/tags.feature b/features/project/commits/tags.feature deleted file mode 100644 index 02f399f7cad9038ee4ddc900c2d0261a21d4059c..0000000000000000000000000000000000000000 --- a/features/project/commits/tags.feature +++ /dev/null @@ -1,41 +0,0 @@ -Feature: Project Commits Tags - Background: - Given I sign in as a user - And I own project "Shop" - Given I visit project tags page - - Scenario: I can see all git tags - Then I should see "Shop" all tags list - - Scenario: I create a tag - And I click new tag link - And I submit new tag form - Then I should see new tag created - - Scenario: I create a tag with invalid name - And I click new tag link - And I submit new tag form with invalid name - Then I should see new an error that tag is invalid - - Scenario: I create a tag with invalid reference - And I click new tag link - And I submit new tag form with invalid reference - Then I should see new an error that tag ref is invalid - - Scenario: I create a tag that already exists - And I click new tag link - And I submit new tag form with tag that already exists - Then I should see new an error that tag already exists - - @javascript - Scenario: I delete a tag - Given I delete tag 'v1.1.0' - Then I should not see tag 'v1.1.0' - - @javascript - Scenario: I delete all tags and see info message - Given I delete all tags - Then I should see tags info message - - # @wip - # Scenario: I can download project by tag diff --git a/features/project/commits/user_lookup.feature b/features/project/commits/user_lookup.feature deleted file mode 100644 index db51d4a6cfa94f7afc72b268be3931349fd4497e..0000000000000000000000000000000000000000 --- a/features/project/commits/user_lookup.feature +++ /dev/null @@ -1,15 +0,0 @@ -Feature: Project Commits User Lookup - Background: - Given I sign in as a user - And I own a project - And I visit my project's commits page - - Scenario: I browse commit from list - Given I have user with primary email - When I click on commit link - Then I see author based on primary email - - Scenario: I browse another commit from list - Given I have user with secondary email - When I click on another commit link - Then I see author based on secondary email diff --git a/features/project/create.feature b/features/project/create.feature deleted file mode 100644 index e9dc4fe6b3c4d83b06e2dd49f867904c541b2980..0000000000000000000000000000000000000000 --- a/features/project/create.feature +++ /dev/null @@ -1,23 +0,0 @@ -Feature: Project Create - In order to get access to project sections - A user with ability to create a project - Should be able to create a new one - - @javascript - Scenario: User create a project - Given I sign in as a user - When I visit new project page - And fill project form with valid data - Then I should see project page - And I should see empty project instuctions - - @javascript - Scenario: Empty project instructions - Given I sign in as a user - When I visit new project page - And fill project form with valid data - Then I see empty project instuctions - And I click on HTTP - Then Remote url should update to http link - And If I click on SSH - Then Remote url should update to ssh link diff --git a/features/project/deploy_keys.feature b/features/project/deploy_keys.feature deleted file mode 100644 index a71f6124d9c3a0af54a62ddd9a37d9bbebd731b9..0000000000000000000000000000000000000000 --- a/features/project/deploy_keys.feature +++ /dev/null @@ -1,40 +0,0 @@ -Feature: Project Deploy Keys - Background: - Given I sign in as a user - And I own project "Shop" - - Scenario: I should see deploy keys list - Given project has deploy key - When I visit project deploy keys page - Then I should see project deploy key - - Scenario: I should see project deploy keys - Given other project has deploy key - When I visit project deploy keys page - Then I should see other project deploy key - - Scenario: I should see public deploy keys - Given public deploy key exists - When I visit project deploy keys page - Then I should see public deploy key - - Scenario: I add new deploy key - Given I visit project deploy keys page - When I click 'New Deploy Key' - And I submit new deploy key - Then I should be on deploy keys page - And I should see newly created deploy key - - Scenario: I attach other project deploy key to project - Given other project has deploy key - And I visit project deploy keys page - When I click attach deploy key - Then I should be on deploy keys page - And I should see newly created deploy key - - Scenario: I attach public deploy key to project - Given public deploy key exists - And I visit project deploy keys page - When I click attach deploy key - Then I should be on deploy keys page - And I should see newly created deploy key diff --git a/features/project/fork.feature b/features/project/fork.feature deleted file mode 100644 index 22f68e5b340e28940dcc6cc814d80f49fcf6088e..0000000000000000000000000000000000000000 --- a/features/project/fork.feature +++ /dev/null @@ -1,16 +0,0 @@ -Feature: Project Fork - Background: - Given I sign in as a user - And I am a member of project "Shop" - When I visit project "Shop" page - - Scenario: User fork a project - Given I click link "Fork" - When I fork to my namespace - Then I should see the forked project page - - Scenario: User already has forked the project - Given I already have a project named "Shop" in my namespace - And I click link "Fork" - When I fork to my namespace - Then I should see a "Name has already been taken" warning diff --git a/features/project/forked_merge_requests.feature b/features/project/forked_merge_requests.feature deleted file mode 100644 index d9fbb875c2864aff75947d5585f4e0d28e4a80c0..0000000000000000000000000000000000000000 --- a/features/project/forked_merge_requests.feature +++ /dev/null @@ -1,40 +0,0 @@ -Feature: Project Forked Merge Requests - Background: - Given I sign in as a user - And I am a member of project "Shop" - And I have a project forked off of "Shop" called "Forked Shop" - - Scenario: I submit new unassigned merge request to a forked project - Given I visit project "Forked Shop" merge requests page - And I click link "New Merge Request" - And I fill out a "Merge Request On Forked Project" merge request - And I submit the merge request - Then I should see merge request "Merge Request On Forked Project" - - # TODO: Improve it so it does not fail randomly - # - #@javascript - #Scenario: I can edit a forked merge request - #Given I visit project "Forked Shop" merge requests page - #And I click link "New Merge Request" - #And I fill out a "Merge Request On Forked Project" merge request - #And I submit the merge request - #And I should see merge request "Merge Request On Forked Project" - #And I click link edit "Merge Request On Forked Project" - #Then I see the edit page prefilled for "Merge Request On Forked Project" - #And I update the merge request title - #And I save the merge request - #Then I should see the edited merge request - - @javascript - Scenario: I cannot submit an invalid merge request - Given I visit project "Forked Shop" merge requests page - And I click link "New Merge Request" - And I fill out an invalid "Merge Request On Forked Project" merge request - Then I should see validation errors - - @javascript - Scenario: Merge request should target fork repository by default - Given I visit project "Forked Shop" merge requests page - And I click link "New Merge Request" - Then the target repository should be the original repository diff --git a/features/project/graph.feature b/features/project/graph.feature deleted file mode 100644 index 89064242c1cbf8a04d53732b328e2022f8255bfd..0000000000000000000000000000000000000000 --- a/features/project/graph.feature +++ /dev/null @@ -1,14 +0,0 @@ -Feature: Project Graph - Background: - Given I sign in as a user - And I own project "Shop" - - @javascript - Scenario: I should see project graphs - When I visit project "Shop" graph page - Then page should have graphs - - @javascript - Scenario: I should see project commits graphs - When I visit project "Shop" commits graph page - Then page should have commits graphs diff --git a/features/project/hooks.feature b/features/project/hooks.feature deleted file mode 100644 index 1a60846a23e6eb79e020324699fbb6c9c76709d1..0000000000000000000000000000000000000000 --- a/features/project/hooks.feature +++ /dev/null @@ -1,32 +0,0 @@ -Feature: Project Hooks - Background: - Given I sign in as a user - And I own project "Shop" - - Scenario: I should see hook list - Given project has hook - When I visit project hooks page - Then I should see project hook - - Scenario: I add new hook - Given I visit project hooks page - When I submit new hook - Then I should see newly created hook - - Scenario: I test hook - Given project has hook - And I visit project hooks page - When I click test hook button - Then hook should be triggered - - Scenario: I test a hook on empty project - Given I own empty project with hook - And I visit project hooks page - When I click test hook button - Then I should see hook error message - - Scenario: I test a hook on down URL - Given project has hook - And I visit project hooks page - When I click test hook button with invalid URL - Then I should see hook service down error message diff --git a/features/project/issues/filter_labels.feature b/features/project/issues/filter_labels.feature deleted file mode 100644 index e316f519861ec86a4a622b60c6ec487a3f5acc8d..0000000000000000000000000000000000000000 --- a/features/project/issues/filter_labels.feature +++ /dev/null @@ -1,26 +0,0 @@ -Feature: Project Issues Filter Labels - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has labels: "bug", "feature", "enhancement" - And project "Shop" has issue "Bugfix1" with labels: "bug", "feature" - And project "Shop" has issue "Bugfix2" with labels: "bug", "enhancement" - And project "Shop" has issue "Feature1" with labels: "feature" - Given I visit project "Shop" issues page - - @javascript - Scenario: I filter by one label - Given I click link "bug" - Then I should see "Bugfix1" in issues list - And I should see "Bugfix2" in issues list - And I should not see "Feature1" in issues list - - # TODO: make labels filter works according to this scanario - # right now it looks for label 1 OR label 2. Old behaviour (this test) was - # all issues that have both label 1 AND label 2 - #Scenario: I filter by two labels - #Given I click link "bug" - #And I click link "feature" - #Then I should see "Bugfix1" in issues list - #And I should not see "Bugfix2" in issues list - #And I should not see "Feature1" in issues list diff --git a/features/project/issues/issues.feature b/features/project/issues/issues.feature deleted file mode 100644 index eb813884d1e5598613f9e7fd1370d97b33620e5e..0000000000000000000000000000000000000000 --- a/features/project/issues/issues.feature +++ /dev/null @@ -1,219 +0,0 @@ -Feature: Project Issues - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" have "Release 0.4" open issue - And project "Shop" have "Tweet control" open issue - And project "Shop" have "Release 0.3" closed issue - And I visit project "Shop" issues page - - Scenario: I should see open issues - Given I should see "Release 0.4" in issues - And I should not see "Release 0.3" in issues - - Scenario: I should see closed issues - Given I click link "Closed" - Then I should see "Release 0.3" in issues - And I should not see "Release 0.4" in issues - - Scenario: I should see all issues - Given I click link "All" - Then I should see "Release 0.3" in issues - And I should see "Release 0.4" in issues - - Scenario: I visit issue page - Given I click link "Release 0.4" - Then I should see issue "Release 0.4" - - @javascript - Scenario: I visit issue page - Given I add a user to project "Shop" - And I click "author" dropdown - Then I see current user as the first user - - Scenario: I submit new unassigned issue - Given I click link "New Issue" - And I submit new issue "500 error on profile" - Then I should see issue "500 error on profile" - - Scenario: I submit new unassigned issue with labels - Given project "Shop" has labels: "bug", "feature", "enhancement" - And I click link "New Issue" - And I submit new issue "500 error on profile" with label 'bug' - Then I should see issue "500 error on profile" - And I should see label 'bug' with issue - - @javascript - Scenario: I comment issue - Given I visit issue page "Release 0.4" - And I leave a comment like "XML attached" - Then I should see comment "XML attached" - And I should see an error alert section within the comment form - - @javascript - Scenario: I search issue - Given I fill in issue search with "Re" - Then I should see "Release 0.4" in issues - And I should not see "Release 0.3" in issues - And I should not see "Tweet control" in issues - - @javascript - Scenario: I search issue that not exist - Given I fill in issue search with "Bu" - Then I should not see "Release 0.4" in issues - And I should not see "Release 0.3" in issues - - @javascript - Scenario: I search all issues - Given I click link "All" - And I fill in issue search with ".3" - Then I should see "Release 0.3" in issues - And I should not see "Release 0.4" in issues - - @javascript - Scenario: Search issues when search string exactly matches issue description - Given project 'Shop' has issue 'Bugfix1' with description: 'Description for issue1' - And I fill in issue search with 'Description for issue1' - Then I should see 'Bugfix1' in issues - And I should not see "Release 0.4" in issues - And I should not see "Release 0.3" in issues - And I should not see "Tweet control" in issues - - @javascript - Scenario: Search issues when search string partially matches issue description - Given project 'Shop' has issue 'Bugfix1' with description: 'Description for issue1' - And project 'Shop' has issue 'Feature1' with description: 'Feature submitted for issue1' - And I fill in issue search with 'issue1' - Then I should see 'Feature1' in issues - Then I should see 'Bugfix1' in issues - And I should not see "Release 0.4" in issues - And I should not see "Release 0.3" in issues - And I should not see "Tweet control" in issues - - @javascript - Scenario: Search issues when search string matches no issue description - Given project 'Shop' has issue 'Bugfix1' with description: 'Description for issue1' - And I fill in issue search with 'Rock and roll' - Then I should not see 'Bugfix1' in issues - And I should not see "Release 0.4" in issues - And I should not see "Release 0.3" in issues - And I should not see "Tweet control" in issues - - - # Markdown - - Scenario: Headers inside the description should have ids generated for them. - Given I visit issue page "Release 0.4" - Then Header "Description header" should have correct id and link - - @javascript - Scenario: Headers inside comments should not have ids generated for them. - Given I visit issue page "Release 0.4" - And I leave a comment with a header containing "Comment with a header" - Then The comment with the header should not have an ID - - @javascript - Scenario: Blocks inside comments should not build relative links - Given I visit issue page "Release 0.4" - And I leave a comment with code block - Then The code block should be unchanged - - Scenario: Issues on empty project - Given empty project "Empty Project" - When I visit empty project page - And I see empty project details with ssh clone info - When I visit empty project's issues page - Given I click link "New Issue" - And I submit new issue "500 error on profile" - Then I should see issue "500 error on profile" - - Scenario: Clickable labels - Given issue 'Release 0.4' has label 'bug' - And I visit project "Shop" issues page - When I click label 'bug' - And I should see "Release 0.4" in issues - And I should not see "Tweet control" in issues - - Scenario: Issue description should render task checkboxes - Given project "Shop" has "Tasks-open" open issue with task markdown - When I visit issue page "Tasks-open" - Then I should see task checkboxes in the description - - @javascript - Scenario: Issue notes should not render task checkboxes - Given project "Shop" has "Tasks-open" open issue with task markdown - When I visit issue page "Tasks-open" - And I leave a comment with task markdown - Then I should not see task checkboxes in the comment - - @javascript - Scenario: Issue notes should be editable with +1 - Given project "Shop" has "Tasks-open" open issue with task markdown - When I visit issue page "Tasks-open" - And I leave a comment with a header containing "Comment with a header" - Then The comment with the header should not have an ID - And I edit the last comment with a +1 - Then I should see +1 in the description - - # Task status in issues list - - Scenario: Issues list should display task status - Given project "Shop" has "Tasks-open" open issue with task markdown - When I visit project "Shop" issues page - Then I should see the task status for the Taskable - - # Toggling task items - - @javascript - Scenario: Task checkboxes should be enabled for an open issue - Given project "Shop" has "Tasks-open" open issue with task markdown - When I visit issue page "Tasks-open" - Then Task checkboxes should be enabled - - @javascript - Scenario: Task checkboxes should be disabled for a closed issue - Given project "Shop" has "Tasks-closed" closed issue with task markdown - When I visit issue page "Tasks-closed" - Then Task checkboxes should be disabled - - # Issue description preview - - @javascript - Scenario: I can't preview without text - Given I click link "New Issue" - And I haven't written any description text - Then The Markdown preview tab should say there is nothing to do - - @javascript - Scenario: I can preview with text - Given I click link "New Issue" - And I write a description like ":+1: Nice" - Then The Markdown preview tab should display rendered Markdown - - @javascript - Scenario: I preview an issue description - Given I click link "New Issue" - And I preview a description text like "Bug fixed :smile:" - Then I should see the Markdown preview - And I should not see the Markdown text field - - @javascript - Scenario: I can edit after preview - Given I click link "New Issue" - And I preview a description text like "Bug fixed :smile:" - Then I should see the Markdown write tab - - @javascript - Scenario: I can preview when editing an existing issue - Given I click link "Release 0.4" - And I click link "Edit" for the issue - And I preview a description text like "Bug fixed :smile:" - Then I should see the Markdown write tab - - @javascript - Scenario: I can unsubscribe from issue - Given project "Shop" has "Tasks-open" open issue with task markdown - When I visit issue page "Tasks-open" - Then I should see that I am subscribed - When I click button "Unsubscribe" - Then I should see that I am unsubscribed diff --git a/features/project/issues/labels.feature b/features/project/issues/labels.feature deleted file mode 100644 index 039a7d83cb1926a36bed98b352f366b165ac0774..0000000000000000000000000000000000000000 --- a/features/project/issues/labels.feature +++ /dev/null @@ -1,47 +0,0 @@ -Feature: Project Issues Labels - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has labels: "bug", "feature", "enhancement" - Given I visit project "Shop" labels page - - Scenario: I should see labels list - Then I should see label 'bug' - And I should see label 'feature' - - Scenario: I create new label - Given I visit project "Shop" new label page - When I submit new label 'support' - Then I should see label 'support' - - Scenario: I edit label - Given I visit 'bug' label edit page - When I change label 'bug' to 'fix' - Then I should not see label 'bug' - Then I should see label 'fix' - - Scenario: I remove label - When I remove label 'bug' - Then I should not see label 'bug' - - @javascript - Scenario: I remove all labels - When I delete all labels - Then I should see labels help message - - Scenario: I create a label with invalid color - Given I visit project "Shop" new label page - When I submit new label with invalid color - Then I should see label color error message - - Scenario: I create a label that already exists - Given I visit project "Shop" new label page - When I submit new label 'bug' - Then I should see label label exist error message - - Scenario: I create the same label on another project - Given I own project "Forum" - And I visit project "Forum" labels page - And I visit project "Forum" new label page - When I submit new label 'bug' - Then I should see label 'bug' diff --git a/features/project/issues/milestones.feature b/features/project/issues/milestones.feature deleted file mode 100644 index 9ac65b1257cf6e4f960375515a8f9a174582ab27..0000000000000000000000000000000000000000 --- a/features/project/issues/milestones.feature +++ /dev/null @@ -1,30 +0,0 @@ -Feature: Project Issues Milestones - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has milestone "v2.2" - Given I visit project "Shop" milestones page - - Scenario: I should see active milestones - Then I should see milestone "v2.2" - - Scenario: I should see milestone - Given I click link "v2.2" - Then I should see milestone "v2.2" - - Scenario: I create new milestone - Given I click link "New Milestone" - And I submit new milestone "v2.3" - Then I should see milestone "v2.3" - - @javascript - Scenario: Listing closed issues - Given the milestone has open and closed issues - And I click link "v2.2" - Then I should see 3 issues - - # Markdown - - Scenario: Headers inside the description should have ids generated for them. - Given I click link "v2.2" - Then Header "Description header" should have correct id and link diff --git a/features/project/merge_requests.feature b/features/project/merge_requests.feature deleted file mode 100644 index cbb5c8eb39b6bb6331dfc21d6c917884e3938343..0000000000000000000000000000000000000000 --- a/features/project/merge_requests.feature +++ /dev/null @@ -1,241 +0,0 @@ -Feature: Project Merge Requests - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" have "Bug NS-04" open merge request - And project "Shop" have "Feature NS-03" closed merge request - And I visit project "Shop" merge requests page - - Scenario: I should see open merge requests - Then I should see "Bug NS-04" in merge requests - And I should not see "Feature NS-03" in merge requests - - Scenario: I should see closed merge requests - Given I click link "Closed" - Then I should see "Feature NS-03" in merge requests - And I should not see "Bug NS-04" in merge requests - - Scenario: I should see all merge requests - Given I click link "All" - Then I should see "Feature NS-03" in merge requests - And I should see "Bug NS-04" in merge requests - - Scenario: I visit merge request page - Given I click link "Bug NS-04" - Then I should see merge request "Bug NS-04" - - Scenario: I close merge request page - Given I click link "Bug NS-04" - And I click link "Close" - Then I should see closed merge request "Bug NS-04" - - Scenario: I reopen merge request page - Given I click link "Bug NS-04" - And I click link "Close" - Then I should see closed merge request "Bug NS-04" - When I click link "Reopen" - Then I should see reopened merge request "Bug NS-04" - - Scenario: I submit new unassigned merge request - Given I click link "New Merge Request" - And I submit new merge request "Wiki Feature" - Then I should see merge request "Wiki Feature" - - @javascript - Scenario: I comment on a merge request - Given I visit merge request page "Bug NS-04" - And I leave a comment like "XML attached" - Then I should see comment "XML attached" - - @javascript - Scenario: I comment on a merge request diff - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I switch to the diff tab - And I leave a comment like "Line is wrong" on diff - And I switch to the merge request's comments tab - Then I should see a discussion has started on diff - - @javascript - Scenario: I comment on a line of a commit in merge request - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I click on the commit in the merge request - And I leave a comment like "Line is wrong" on diff in commit - And I switch to the merge request's comments tab - Then I should see a discussion has started on commit diff - - @javascript - Scenario: I comment on a commit in merge request - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I click on the commit in the merge request - And I leave a comment on the diff page in commit - And I switch to the merge request's comments tab - Then I should see a discussion has started on commit - - @javascript - Scenario: I accept merge request with custom commit message - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And merge request "Bug NS-05" is mergeable - And I visit merge request page "Bug NS-05" - And merge request is mergeable - Then I modify merge commit message - And I accept this merge request - Then I should see merged request - - # Markdown - - Scenario: Headers inside the description should have ids generated for them. - When I visit merge request page "Bug NS-04" - Then Header "Description header" should have correct id and link - - @javascript - Scenario: Headers inside comments should not have ids generated for them. - Given I visit merge request page "Bug NS-04" - And I leave a comment with a header containing "Comment with a header" - Then The comment with the header should not have an ID - - Scenario: Merge request description should render task checkboxes - Given project "Shop" has "MR-task-open" open MR with task markdown - When I visit merge request page "MR-task-open" - Then I should see task checkboxes in the description - - Scenario: Merge request notes should not render task checkboxes - Given project "Shop" has "MR-task-open" open MR with task markdown - When I visit merge request page "MR-task-open" - Then I should not see task checkboxes in the comment - - # Toggling inline comments - - @javascript - Scenario: I hide comments on a merge request diff with comments in a single file - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I switch to the diff tab - And I leave a comment like "Line is wrong" on line 39 of the second file - And I click link "Hide inline discussion" of the second file - Then I should not see a comment like "Line is wrong here" in the second file - - @javascript - Scenario: I show comments on a merge request diff with comments in a single file - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I switch to the diff tab - And I leave a comment like "Line is wrong" on line 39 of the second file - Then I should see a comment like "Line is wrong" in the second file - - @javascript - Scenario: I hide comments on a merge request diff with comments in multiple files - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I switch to the diff tab - And I leave a comment like "Line is correct" on line 12 of the first file - And I leave a comment like "Line is wrong" on line 39 of the second file - And I click link "Hide inline discussion" of the second file - Then I should not see a comment like "Line is wrong here" in the second file - And I should still see a comment like "Line is correct" in the first file - - @javascript - Scenario: I show comments on a merge request diff with comments in multiple files - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I switch to the diff tab - And I leave a comment like "Line is correct" on line 12 of the first file - And I leave a comment like "Line is wrong" on line 39 of the second file - And I click link "Hide inline discussion" of the second file - And I click link "Show inline discussion" of the second file - Then I should see a comment like "Line is wrong" in the second file - And I should still see a comment like "Line is correct" in the first file - - @javascript - Scenario: I unfold diff - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I switch to the diff tab - And I unfold diff - Then I should see additional file lines - - @javascript - Scenario: I show comments on a merge request side-by-side diff with comments in multiple files - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I switch to the diff tab - And I leave a comment like "Line is correct" on line 12 of the first file - And I leave a comment like "Line is wrong" on line 39 of the second file - And I click Side-by-side Diff tab - Then I should see comments on the side-by-side diff page - - @javascript - Scenario: I view diffs on a merge request - Given project "Shop" have "Bug NS-05" open merge request with diffs inside - And I visit merge request page "Bug NS-05" - And I click on the Changes tab via Javascript - Then I should see the proper Inline and Side-by-side links - - # Task status in issues list - - Scenario: Merge requests list should display task status - Given project "Shop" has "MR-task-open" open MR with task markdown - When I visit project "Shop" merge requests page - Then I should see the task status for the Taskable - - # Toggling task items - - @javascript - Scenario: Task checkboxes should be enabled for an open merge request - Given project "Shop" has "MR-task-open" open MR with task markdown - When I visit merge request page "MR-task-open" - Then Task checkboxes should be enabled - - @javascript - Scenario: Task checkboxes should be disabled for a closed merge request - Given project "Shop" has "MR-task-open" open MR with task markdown - And I visit merge request page "MR-task-open" - And I click link "Close" - Then Task checkboxes should be disabled - - # Description preview - - @javascript - Scenario: I can't preview without text - Given I visit merge request page "Bug NS-04" - And I click link "Edit" for the merge request - And I haven't written any description text - Then The Markdown preview tab should say there is nothing to do - - @javascript - Scenario: I can preview with text - Given I visit merge request page "Bug NS-04" - And I click link "Edit" for the merge request - And I write a description like ":+1: Nice" - Then The Markdown preview tab should display rendered Markdown - - @javascript - Scenario: I preview a merge request description - Given I visit merge request page "Bug NS-04" - And I click link "Edit" for the merge request - And I preview a description text like "Bug fixed :smile:" - Then I should see the Markdown preview - And I should not see the Markdown text field - - @javascript - Scenario: I can edit after preview - Given I visit merge request page "Bug NS-04" - And I click link "Edit" for the merge request - And I preview a description text like "Bug fixed :smile:" - Then I should see the Markdown write tab - - @javascript - Scenario: I search merge request - Given I click link "All" - When I fill in merge request search with "Fe" - Then I should see "Feature NS-03" in merge requests - And I should not see "Bug NS-04" in merge requests - - @javascript - Scenario: I can unsubscribe from merge request - Given I visit merge request page "Bug NS-04" - Then I should see that I am subscribed - When I click button "Unsubscribe" - Then I should see that I am unsubscribed diff --git a/features/project/network_graph.feature b/features/project/network_graph.feature deleted file mode 100644 index 8beb6043affce4d1261886f893b4335c7d555ac0..0000000000000000000000000000000000000000 --- a/features/project/network_graph.feature +++ /dev/null @@ -1,40 +0,0 @@ -Feature: Project Network Graph - Background: - Given I sign in as a user - And I own project "Shop" - And I visit project "Shop" network page - - @javascript - Scenario: I should see project network - Then page should have network graph - And page should select "master" in select box - And page should have "master" on graph - - @javascript - Scenario: I should switch "branch" and "tag" - When I switch ref to "feature" - Then page should select "feature" in select box - And page should have "feature" on graph - When I switch ref to "v1.0.0" - Then page should select "v1.0.0" in select box - And page should have "v1.0.0" on graph - - @javascript - Scenario: I should looking for a commit by SHA - When I looking for a commit by SHA of "v1.0.0" - Then page should have network graph - And page should select "master" in select box - And page should have "v1.0.0" on graph - - @javascript - Scenario: I should filter selected tag - When I switch ref to "v1.0.0" - Then page should have content not containing "v1.0.0" - When click "Show only selected branch" checkbox - Then page should not have content not containing "v1.0.0" - When click "Show only selected branch" checkbox - Then page should have content not containing "v1.0.0" - - Scenario: I should fail to look for a commit - When I look for a commit by ";" - Then page status code should be 404 diff --git a/features/project/project.feature b/features/project/project.feature deleted file mode 100644 index 3e1fd54bee84ca92fcbb4cd61880287715e6e0b4..0000000000000000000000000000000000000000 --- a/features/project/project.feature +++ /dev/null @@ -1,57 +0,0 @@ -Feature: Project - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" has push event - And I visit project "Shop" page - - Scenario: I edit the project avatar - Given I visit edit project "Shop" page - When I change the project avatar - And I should see new project avatar - And I should see the "Remove avatar" button - - Scenario: I remove the project avatar - Given I visit edit project "Shop" page - And I have an project avatar - When I remove my project avatar - Then I should see the default project avatar - And I should not see the "Remove avatar" button - - @javascript - Scenario: I should see project activity - When I visit project "Shop" page - Then I should see project "Shop" activity feed - - Scenario: I visit edit project - When I visit edit project "Shop" page - Then I should see project settings - - Scenario: I edit project - When I visit edit project "Shop" page - And change project settings - And I save project - Then I should see project with new settings - - Scenario: I change project path - When I visit edit project "Shop" page - And change project path settings - Then I should see project with new path settings - - Scenario: I should see project readme and version - When I visit project "Shop" page - And I should see project "Shop" version - - Scenario: I should change project default branch - When I visit edit project "Shop" page - And change project default branch - And I save project - Then I should see project default branch changed - - @javascript - Scenario: I should have default tab per my preference - And I own project "Forum" - When I select project "Forum" README tab - Then I should see project "Forum" README - And I visit project "Shop" page - Then I should see project "Shop" README diff --git a/features/project/redirects.feature b/features/project/redirects.feature deleted file mode 100644 index a2e77e7bf3091e934bcc09730c41df61c9e0811a..0000000000000000000000000000000000000000 --- a/features/project/redirects.feature +++ /dev/null @@ -1,38 +0,0 @@ -Feature: Project Redirects - Background: - Given public project "Community" - And private project "Enterprise" - - Scenario: I visit public project page - When I visit project "Community" page - Then I should see project "Community" home page - - Scenario: I visit private project page - When I visit project "Enterprise" page - Then I should be redirected to sign in page - - Scenario: I visit a non-existent project page - When I visit project "CommunityDoesNotExist" page - Then I should be redirected to sign in page - - Scenario: I visit a non-existent project page as user - Given I sign in as a user - When I visit project "CommunityDoesNotExist" page - Then page status code should be 404 - - Scenario: I visit unauthorized project page as user - Given I sign in as a user - When I visit project "Enterprise" page - Then page status code should be 404 - - Scenario: I visit a public project without signing in - When I visit project "Community" page - And I should see project "Community" home page - And I click on "Sign In" - And Authenticate - Then I should be redirected to "Community" page - - Scenario: I visit private project page without signing in - When I visit project "Enterprise" page - And I get redirected to signin page where I sign in - Then I should be redirected to "Enterprise" page diff --git a/features/project/service.feature b/features/project/service.feature deleted file mode 100644 index fdff640ec857e1ea267fbf77af7d3312a266c2d7..0000000000000000000000000000000000000000 --- a/features/project/service.feature +++ /dev/null @@ -1,86 +0,0 @@ -Feature: Project Services - Background: - Given I sign in as a user - And I own project "Shop" - - Scenario: I should see project services - When I visit project "Shop" services page - Then I should see list of available services - - Scenario: Activate gitlab-ci service - When I visit project "Shop" services page - And I click gitlab-ci service link - And I fill gitlab-ci settings - Then I should see service settings saved - - Scenario: Activate hipchat service - When I visit project "Shop" services page - And I click hipchat service link - And I fill hipchat settings - Then I should see hipchat service settings saved - - Scenario: Activate hipchat service with custom server - When I visit project "Shop" services page - And I click hipchat service link - And I fill hipchat settings with custom server - Then I should see hipchat service settings with custom server saved - - Scenario: Activate pivotaltracker service - When I visit project "Shop" services page - And I click pivotaltracker service link - And I fill pivotaltracker settings - Then I should see pivotaltracker service settings saved - - Scenario: Activate Flowdock service - When I visit project "Shop" services page - And I click Flowdock service link - And I fill Flowdock settings - Then I should see Flowdock service settings saved - - Scenario: Activate Assembla service - When I visit project "Shop" services page - And I click Assembla service link - And I fill Assembla settings - Then I should see Assembla service settings saved - - Scenario: Activate Slack service - When I visit project "Shop" services page - And I click Slack service link - And I fill Slack settings - Then I should see Slack service settings saved - - Scenario: Activate Pushover service - When I visit project "Shop" services page - And I click Pushover service link - And I fill Pushover settings - Then I should see Pushover service settings saved - - Scenario: Activate email on push service - When I visit project "Shop" services page - And I click email on push service link - And I fill email on push settings - Then I should see email on push service settings saved - - Scenario: Activate Irker (IRC Gateway) service - When I visit project "Shop" services page - And I click Irker service link - And I fill Irker settings - Then I should see Irker service settings saved - - Scenario: Activate Atlassian Bamboo CI service - When I visit project "Shop" services page - And I click Atlassian Bamboo CI service link - And I fill Atlassian Bamboo CI settings - Then I should see Atlassian Bamboo CI service settings saved - - Scenario: Activate jetBrains TeamCity CI service - When I visit project "Shop" services page - And I click jetBrains TeamCity CI service link - And I fill jetBrains TeamCity CI settings - Then I should see jetBrains TeamCity CI service settings saved - - Scenario: Activate Asana service - When I visit project "Shop" services page - And I click Asana service link - And I fill Asana settings - Then I should see Asana service settings saved diff --git a/features/project/shortcuts.feature b/features/project/shortcuts.feature deleted file mode 100644 index cfb68bf1f50c6bef2f98a2cf90815cc49419c8af..0000000000000000000000000000000000000000 --- a/features/project/shortcuts.feature +++ /dev/null @@ -1,52 +0,0 @@ -@dashboard -Feature: Project Shortcuts - Background: - Given I sign in as a user - And I own a project - And I visit my project's home page - - @javascript - Scenario: Navigate to files tab - Given I press "g" and "f" - Then the active main tab should be Files - - @javascript - Scenario: Navigate to commits tab - Given I press "g" and "c" - Then the active main tab should be Commits - - @javascript - Scenario: Navigate to network tab - Given I press "g" and "n" - Then the active main tab should be Network - - @javascript - Scenario: Navigate to graphs tab - Given I press "g" and "g" - Then the active main tab should be Graphs - - @javascript - Scenario: Navigate to issues tab - Given I press "g" and "i" - Then the active main tab should be Issues - - @javascript - Scenario: Navigate to merge requests tab - Given I press "g" and "m" - Then the active main tab should be Merge Requests - - @javascript - Scenario: Navigate to snippets tab - Given I press "g" and "s" - Then the active main tab should be Snippets - - @javascript - Scenario: Navigate to wiki tab - Given I press "g" and "w" - Then the active main tab should be Wiki - - @javascript - Scenario: Navigate to project feed - Given I visit my project's files page - Given I press "g" and "p" - Then the active main tab should be Home diff --git a/features/project/snippets.feature b/features/project/snippets.feature deleted file mode 100644 index 77e42a1a38b93bc146942348a9b24e33d730713a..0000000000000000000000000000000000000000 --- a/features/project/snippets.feature +++ /dev/null @@ -1,34 +0,0 @@ -Feature: Project Snippets - Background: - Given I sign in as a user - And I own project "Shop" - And project "Shop" have "Snippet one" snippet - And project "Shop" have no "Snippet two" snippet - And I visit project "Shop" snippets page - - Scenario: I should see snippets - Given I visit project "Shop" snippets page - Then I should see "Snippet one" in snippets - And I should not see "Snippet two" in snippets - - Scenario: I create new project snippet - Given I click link "New Snippet" - And I submit new snippet "Snippet three" - Then I should see snippet "Snippet three" - - @javascript - Scenario: I comment on a snippet "Snippet one" - Given I visit snippet page "Snippet one" - And I leave a comment like "Good snippet!" - Then I should see comment "Good snippet!" - - Scenario: I update "Snippet one" - Given I visit snippet page "Snippet one" - And I click link "Edit" - And I submit new title "Snippet new title" - Then I should see "Snippet new title" - - Scenario: I destroy "Snippet one" - Given I visit snippet page "Snippet one" - And I click link "Remove Snippet" - Then I should not see "Snippet one" in snippets diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature deleted file mode 100644 index 90b966dd6455a54115c85f82f644eb0a829420c5..0000000000000000000000000000000000000000 --- a/features/project/source/browse_files.feature +++ /dev/null @@ -1,160 +0,0 @@ -Feature: Project Source Browse Files - Background: - Given I sign in as a user - And I own project "Shop" - Given I visit project source page - - Scenario: I browse files from master branch - Then I should see files from repository - - Scenario: I browse files for specific ref - Given I visit project source page for "6d39438" - Then I should see files from repository for "6d39438" - - Scenario: I browse file content - Given I click on ".gitignore" file in repo - Then I should see its content - - Scenario: I browse raw file - Given I visit blob file from repo - And I click link "Raw" - Then I should see raw file content - - Scenario: I can create file - Given I click on "new file" link in repo - Then I can see new file page - - @javascript - Scenario: I can create and commit file - Given I click on "new file" link in repo - And I edit code - And I fill the new file name - And I fill the commit message - And I click on "Commit Changes" - Then I am redirected to the new file - And I should see its new content - - @javascript - Scenario: I can create and commit file and specify new branch - Given I click on "new file" link in repo - And I edit code - And I fill the new file name - And I fill the commit message - And I fill the new branch name - And I click on "Commit Changes" - Then I am redirected to the new file on new branch - And I should see its new content - - @javascript @tricky - Scenario: I can create file in empty repo - Given I own an empty project - And I visit my empty project page - And I create bare repo - When I click on "add a file" link - And I edit code - And I fill the new file name - And I fill the commit message - And I click on "Commit Changes" - Then I am redirected to the new file - And I should see its new content - - @javascript - Scenario: If I enter an illegal file name I see an error message - Given I click on "new file" link in repo - And I fill the new file name with an illegal name - And I edit code - And I fill the commit message - And I click on "Commit changes" - Then I am on the new file page - And I see a commit error message - - @javascript - Scenario: I can edit file - Given I click on ".gitignore" file in repo - And I click button "Edit" - Then I can edit code - - Scenario: If the file is binary the edit link is hidden - Given I visit a binary file in the repo - Then I cannot see the edit button - - Scenario: If I don't have edit permission the edit link is disabled - Given public project "Community" - And I visit project "Community" source page - And I click on ".gitignore" file in repo - Then The edit button is disabled - - @javascript - Scenario: I can edit and commit file - Given I click on ".gitignore" file in repo - And I click button "Edit" - And I edit code - And I fill the commit message - And I click on "Commit Changes" - Then I am redirected to the ".gitignore" - And I should see its new content - - @javascript - Scenario: I can edit and commit file to new branch - Given I click on ".gitignore" file in repo - And I click button "Edit" - And I edit code - And I fill the commit message - And I fill the new branch name - And I click on "Commit Changes" - Then I am redirected to the ".gitignore" on new branch - And I should see its new content - - @javascript @wip - Scenario: If I don't change the content of the file I see an error message - Given I click on ".gitignore" file in repo - And I click button "edit" - And I fill the commit message - And I click on "Commit changes" - # Test fails because carriage returns are added to the file. - Then I am on the ".gitignore" edit file page - And I see a commit error message - - @javascript - Scenario: I can see editing preview - Given I click on ".gitignore" file in repo - And I click button "Edit" - And I edit code - And I click link "Diff" - Then I see diff - - @javascript - Scenario: I can remove file and commit - Given I click on ".gitignore" file in repo - And I see the ".gitignore" - And I click on "Remove" - And I fill the commit message - And I click on "Remove file" - Then I am redirected to the files URL - And I don't see the ".gitignore" - - Scenario: I can browse directory with Browse Dir - Given I click on files directory - And I click on History link - Then I see Browse dir link - - Scenario: I can browse file with Browse File - Given I click on readme file - And I click on History link - Then I see Browse file link - - Scenario: I can browse code with Browse Code - Given I click on History link - Then I see Browse code link - - # Permalink - - Scenario: I click on the permalink link from a branch ref - Given I click on ".gitignore" file in repo - And I click on Permalink - Then I am redirected to the permalink URL - - Scenario: I don't see the permalink link from a SHA ref - Given I visit project source page for "6d394385cf567f80a8fd85055db1ab4c5295806f" - And I click on ".gitignore" file in repo - Then I don't see the permalink link diff --git a/features/project/source/git_blame.feature b/features/project/source/git_blame.feature deleted file mode 100644 index 48b1077dc6b8f5d28cb633d72ce4ca7b732e69c3..0000000000000000000000000000000000000000 --- a/features/project/source/git_blame.feature +++ /dev/null @@ -1,10 +0,0 @@ -Feature: Project Source Git Blame - Background: - Given I sign in as a user - And I own project "Shop" - Given I visit project source page - - Scenario: I blame file - Given I click on ".gitignore" file in repo - And I click Blame button - Then I should see git file blame diff --git a/features/project/source/markdown_render.feature b/features/project/source/markdown_render.feature deleted file mode 100644 index ecbd721c28161646aa4a426361f9f04c20118e05..0000000000000000000000000000000000000000 --- a/features/project/source/markdown_render.feature +++ /dev/null @@ -1,132 +0,0 @@ -Feature: Project Source Markdown Render - Background: - Given I sign in as a user - And I own project "Delta" - And I visit markdown branch - - # Tree README - - Scenario: Tree view should have correct links in README - Given I go directory which contains README file - And I click on a relative link in README - Then I should see the correct markdown - - Scenario: I browse files from markdown branch - Then I should see files from repository in markdown - And I should see rendered README which contains correct links - And I click on Gitlab API in README - Then I should see correct document rendered - - Scenario: I view README in markdown branch - Then I should see files from repository in markdown - And I should see rendered README which contains correct links - And I click on Rake tasks in README - Then I should see correct directory rendered - - Scenario: I view README in markdown branch to see reference links to directory - Then I should see files from repository in markdown - And I should see rendered README which contains correct links - And I click on GitLab API doc directory in README - Then I should see correct doc/api directory rendered - - Scenario: I view README in markdown branch to see reference links to file - Then I should see files from repository in markdown - And I should see rendered README which contains correct links - And I click on Maintenance in README - Then I should see correct maintenance file rendered - - Scenario: README headers should have header links - Then I should see rendered README which contains correct links - And Header "Application details" should have correct id and link - - # Blob - - Scenario: I navigate to doc directory to view documentation in markdown - And I navigate to the doc/api/README - And I see correct file rendered - And I click on users in doc/api/README - Then I should see the correct document file - - Scenario: I navigate to doc directory to view user doc in markdown - And I navigate to the doc/api/README - And I see correct file rendered - And I click on raketasks in doc/api/README - Then I should see correct directory rendered - - Scenario: I navigate to doc directory to view user doc in markdown - And I navigate to the doc/api/README - And Header "GitLab API" should have correct id and link - - # Markdown branch - - Scenario: I browse files from markdown branch - When I visit markdown branch - Then I should see files from repository in markdown branch - And I should see rendered README which contains correct links - And I click on Gitlab API in README - Then I should see correct document rendered for markdown branch - - Scenario: I browse directory from markdown branch - When I visit markdown branch - Then I should see files from repository in markdown branch - And I should see rendered README which contains correct links - And I click on Rake tasks in README - Then I should see correct directory rendered for markdown branch - - Scenario: I navigate to doc directory to view documentation in markdown branch - When I visit markdown branch - And I navigate to the doc/api/README - And I see correct file rendered in markdown branch - And I click on users in doc/api/README - Then I should see the users document file in markdown branch - - Scenario: I navigate to doc directory to view user doc in markdown branch - When I visit markdown branch - And I navigate to the doc/api/README - And I see correct file rendered in markdown branch - And I click on raketasks in doc/api/README - Then I should see correct directory rendered for markdown branch - - Scenario: Tree markdown links view empty urls should have correct urls - When I visit markdown branch - Then The link with text "empty" should have url "tree/markdown" - When I visit markdown branch "README.md" blob - Then The link with text "empty" should have url "blob/markdown/README.md" - When I visit markdown branch "d" tree - Then The link with text "empty" should have url "tree/markdown/d" - When I visit markdown branch "d/README.md" blob - Then The link with text "empty" should have url "blob/markdown/d/README.md" - - # "ID" means "#id" on the tests below, because we are unable to escape the hash sign. - # which Spinach interprets as the start of a comment. - Scenario: All markdown links with ids should have correct urls - When I visit markdown branch - Then The link with text "ID" should have url "tree/markdownID" - Then The link with text "/ID" should have url "tree/markdownID" - Then The link with text "README.mdID" should have url "blob/markdown/README.mdID" - Then The link with text "d/README.mdID" should have url "blob/markdown/d/README.mdID" - When I visit markdown branch "README.md" blob - Then The link with text "ID" should have url "blob/markdown/README.mdID" - Then The link with text "/ID" should have url "blob/markdown/README.mdID" - Then The link with text "README.mdID" should have url "blob/markdown/README.mdID" - Then The link with text "d/README.mdID" should have url "blob/markdown/d/README.mdID" - - # Wiki - - Scenario: I create a wiki page with different links - Given I go to wiki page - And I add various links to the wiki page - Then Wiki page should have added links - And I click on test link - Then I see new wiki page named test - When I go back to wiki page home - And I click on GitLab API doc link - Then I see Gitlab API document - When I go back to wiki page home - And I click on Rake tasks link - Then I see Rake tasks directory - - Scenario: Wiki headers should have should have ids generated for them. - Given I go to wiki page - And I add a header to the wiki page - Then Wiki header should have correct id and link diff --git a/features/project/source/multiselect_blob.feature b/features/project/source/multiselect_blob.feature deleted file mode 100644 index 63b7cb77a9345008f8c31c7003bd5dfa2ce86a96..0000000000000000000000000000000000000000 --- a/features/project/source/multiselect_blob.feature +++ /dev/null @@ -1,85 +0,0 @@ -Feature: Project Source Multiselect Blob - Background: - Given I sign in as a user - And I own project "Shop" - And I visit ".gitignore" file in repo - - @javascript - Scenario: I click line 1 in file - When I click line 1 in file - Then I should see "L1" as URI fragment - And I should see line 1 highlighted - - @javascript - Scenario: I shift-click line 1 in file - When I shift-click line 1 in file - Then I should see "L1" as URI fragment - And I should see line 1 highlighted - - @javascript - Scenario: I click line 1 then click line 2 in file - When I click line 1 in file - Then I should see "L1" as URI fragment - And I should see line 1 highlighted - Then I click line 2 in file - Then I should see "L2" as URI fragment - And I should see line 2 highlighted - - @javascript - Scenario: I click various line numbers to test multiselect - Then I click line 1 in file - Then I should see "L1" as URI fragment - And I should see line 1 highlighted - Then I shift-click line 2 in file - Then I should see "L1-2" as URI fragment - And I should see lines 1-2 highlighted - Then I shift-click line 3 in file - Then I should see "L1-3" as URI fragment - And I should see lines 1-3 highlighted - Then I click line 3 in file - Then I should see "L3" as URI fragment - And I should see line 3 highlighted - Then I shift-click line 1 in file - Then I should see "L1-3" as URI fragment - And I should see lines 1-3 highlighted - Then I shift-click line 5 in file - Then I should see "L1-5" as URI fragment - And I should see lines 1-5 highlighted - Then I shift-click line 4 in file - Then I should see "L1-4" as URI fragment - And I should see lines 1-4 highlighted - Then I click line 5 in file - Then I should see "L5" as URI fragment - And I should see line 5 highlighted - Then I shift-click line 3 in file - Then I should see "L3-5" as URI fragment - And I should see lines 3-5 highlighted - Then I shift-click line 1 in file - Then I should see "L1-3" as URI fragment - And I should see lines 1-3 highlighted - Then I shift-click line 1 in file - Then I should see "L1" as URI fragment - And I should see line 1 highlighted - - @javascript - Scenario: I multiselect lines 1-5 and then go back and forward in history - When I click line 1 in file - And I shift-click line 3 in file - And I shift-click line 2 in file - And I shift-click line 5 in file - Then I should see "L1-5" as URI fragment - And I should see lines 1-5 highlighted - Then I go back in history - Then I should see "L1-2" as URI fragment - And I should see lines 1-2 highlighted - Then I go back in history - Then I should see "L1-3" as URI fragment - And I should see lines 1-3 highlighted - Then I go back in history - Then I should see "L1" as URI fragment - And I should see line 1 highlighted - Then I go forward in history - And I go forward in history - And I go forward in history - Then I should see "L1-5" as URI fragment - And I should see lines 1-5 highlighted diff --git a/features/project/source/search_code.feature b/features/project/source/search_code.feature deleted file mode 100644 index 4f9dcea249fcdce02d53e23a625ed794670f1fe8..0000000000000000000000000000000000000000 --- a/features/project/source/search_code.feature +++ /dev/null @@ -1,15 +0,0 @@ -Feature: Project Source Search Code - Background: - Given I sign in as a user - - Scenario: Search for term "coffee" - Given I own project "Shop" - And I visit project source page - When I search for term "coffee" - Then I should see files from repository containing "coffee" - - Scenario: Search on empty project - Given I own an empty project - And I visit my project's home page - When I search for term "coffee" - Then I should see empty result diff --git a/features/project/star.feature b/features/project/star.feature deleted file mode 100644 index a45f9c470ea8921eb2f023899752af0af6e83d38..0000000000000000000000000000000000000000 --- a/features/project/star.feature +++ /dev/null @@ -1,38 +0,0 @@ -Feature: Project Star - Scenario: New projects have 0 stars - Given public project "Community" - When I visit project "Community" page - Then The project has no stars - - Scenario: Empty projects show star count - Given public empty project "Empty Public Project" - When I visit empty project page - Then The project has no stars - - Scenario: Signed off users can't star projects - Given public project "Community" - And I visit project "Community" page - When I click on the star toggle button - Then I redirected to sign in page - - @javascript - Scenario: Signed in users can toggle star - Given I sign in as "John Doe" - And public project "Community" - And I visit project "Community" page - When I click on the star toggle button - Then The project has 1 star - When I click on the star toggle button - Then The project has 0 stars - - @javascript - Scenario: Star count sums stars - Given I sign in as "John Doe" - And public project "Community" - And I visit project "Community" page - And I click on the star toggle button - And I logout - And I sign in as "Mary Jane" - And I visit project "Community" page - When I click on the star toggle button - Then The project has 2 stars diff --git a/features/project/team_management.feature b/features/project/team_management.feature deleted file mode 100644 index 6cda225ea7bdeb0919ab0890899568c55fcb9e58..0000000000000000000000000000000000000000 --- a/features/project/team_management.feature +++ /dev/null @@ -1,43 +0,0 @@ -Feature: Project Team Management - Background: - Given I sign in as a user - And I own project "Shop" - And gitlab user "Mike" - And gitlab user "Sam" - And "Sam" is "Shop" developer - And I visit project "Shop" team page - - Scenario: See all team members - Then I should be able to see myself in team - And I should see "Sam" in team list - - @javascript - Scenario: Add user to project - Given I click link "Add members" - And I select "Mike" as "Reporter" - Then I should see "Mike" in team list as "Reporter" - - @javascript - Scenario: Invite user to project - Given I click link "Add members" - And I select "sjobs@apple.com" as "Reporter" - Then I should see "sjobs@apple.com" in team list as invited "Reporter" - - @javascript - Scenario: Update user access - Given I should see "Sam" in team list as "Developer" - And I change "Sam" role to "Reporter" - And I should see "Sam" in team list as "Reporter" - - Scenario: Cancel team member - Given I click cancel link for "Sam" - Then I visit project "Shop" team page - And I should not see "Sam" in team list - - Scenario: Import team from another project - Given I own project "Website" - And "Mike" is "Website" reporter - When I visit project "Shop" team page - And I click link "Import team from another project" - And I submit "Website" project for import team - Then I should see "Mike" in team list as "Reporter" diff --git a/features/project/wiki.feature b/features/project/wiki.feature deleted file mode 100644 index 977cd609a117d630c71f949a82e94fdf6997840d..0000000000000000000000000000000000000000 --- a/features/project/wiki.feature +++ /dev/null @@ -1,88 +0,0 @@ -Feature: Project Wiki - Background: - Given I sign in as a user - And I own project "Shop" - Given I visit project wiki page - - Scenario: Add new page - Given I create the Wiki Home page - Then I should see the newly created wiki page - - Scenario: Pressing Cancel while editing a brand new Wiki - Given I click on the Cancel button - Then I should be redirected back to the Edit Home Wiki page - - Scenario: Edit existing page - Given I have an existing Wiki page - And I browse to that Wiki page - And I click on the Edit button - And I change the content - Then I should see the updated content - - Scenario: Pressing Cancel while editing an existing Wiki page - Given I have an existing Wiki page - And I browse to that Wiki page - And I click on the Edit button - And I click on the Cancel button - Then I should be redirected back to that Wiki page - - Scenario: View page history - Given I have an existing wiki page - And That page has two revisions - And I browse to that Wiki page - And I click the History button - Then I should see both revisions - - Scenario: Destroy Wiki page - Given I have an existing wiki page - And I browse to that Wiki page - And I click on the Edit button - And I click on the "Delete this page" button - Then The page should be deleted - - Scenario: View all pages - Given I have an existing wiki page - And I browse to that Wiki page - And I click on the "Pages" button - Then I should see the existing page in the pages list - - Scenario: File exists in wiki repo - Given I have an existing Wiki page with images linked on page - And I browse to wiki page with images - And I click on existing image link - Then I should see the image from wiki repo - - Scenario: Image in wiki repo shown on the page - Given I have an existing Wiki page with images linked on page - And I browse to wiki page with images - Then Image should be shown on the page - - Scenario: File does not exist in wiki repo - Given I have an existing Wiki page with images linked on page - And I browse to wiki page with images - And I click on image link - Then I should see the new wiki page form - - @javascript - Scenario: New Wiki page that has a path - Given I create a New page with paths - And I click on the "Pages" button - Then I should see non-escaped link in the pages list - - @javascript - Scenario: Edit Wiki page that has a path - Given I create a New page with paths - And I click on the "Pages" button - And I edit the Wiki page with a path - Then I should see a non-escaped path - And I should see the Editing page - And I change the content - Then I should see the updated content - - @javascript - Scenario: View the page history of a Wiki page that has a path - Given I create a New page with paths - And I click on the "Pages" button - And I view the page history of a Wiki page that has a path - Then I should see a non-escaped path - And I should see the page history diff --git a/features/search.feature b/features/search.feature deleted file mode 100644 index def21e009234030142e0454ad4eec115db5da98f..0000000000000000000000000000000000000000 --- a/features/search.feature +++ /dev/null @@ -1,46 +0,0 @@ -@dashboard -Feature: Search - Background: - Given I sign in as a user - And I own project "Shop" - And I visit dashboard search page - - Scenario: I should see project I am looking for - Given I search for "Sho" - Then I should see "Shop" project link - - Scenario: I should see issues I am looking for - And project has issues - When I search for "Foo" - And I click "Issues" link - Then I should see "Foo" link in the search results - And I should not see "Bar" link in the search results - - Scenario: I should see merge requests I am looking for - And project has merge requests - When I search for "Foo" - When I click "Merge requests" link - Then I should see "Foo" link in the search results - And I should not see "Bar" link in the search results - - Scenario: I should see project code I am looking for - When I click project "Shop" link - And I search for "rspec" - Then I should see code results for project "Shop" - - Scenario: I should see project issues - And project has issues - When I click project "Shop" link - And I search for "Foo" - And I click "Issues" link - Then I should see "Foo" link in the search results - And I should not see "Bar" link in the search results - - Scenario: I should see project merge requests - And project has merge requests - When I click project "Shop" link - And I search for "Foo" - And I click "Merge requests" link - Then I should see "Foo" link in the search results - And I should not see "Bar" link in the search results - diff --git a/features/snippet_search.feature b/features/snippet_search.feature deleted file mode 100644 index 834bd3b237602f8dd19f00bbce599273635c8190..0000000000000000000000000000000000000000 --- a/features/snippet_search.feature +++ /dev/null @@ -1,20 +0,0 @@ -@dashboard -Feature: Snippet Search - Background: - Given I sign in as a user - And I have public "Personal snippet one" snippet - And I have private "Personal snippet private" snippet - And I have a public many lined snippet - - Scenario: I should see my public and private snippets - When I search for "snippet" in snippet titles - Then I should see "Personal snippet one" in results - And I should see "Personal snippet private" in results - - Scenario: I should see three surrounding lines on either side of a matching snippet line - When I search for "line seven" in snippet contents - Then I should see "line four" in results - And I should see "line seven" in results - And I should see "line ten" in results - And I should not see "line three" in results - And I should not see "line eleven" in results diff --git a/features/snippets/discover.feature b/features/snippets/discover.feature deleted file mode 100644 index 1a7e132ea25261f5e0dc5bc4a621412eab609dea..0000000000000000000000000000000000000000 --- a/features/snippets/discover.feature +++ /dev/null @@ -1,13 +0,0 @@ -@snippets -Feature: Snippets Discover - Background: - Given I sign in as a user - And I have public "Personal snippet one" snippet - And I have private "Personal snippet private" snippet - And I have internal "Personal snippet internal" snippet - - Scenario: I should see snippets - Given I visit snippets page - Then I should see "Personal snippet one" in snippets - And I should see "Personal snippet internal" in snippets - And I should not see "Personal snippet private" in snippets diff --git a/features/snippets/public_snippets.feature b/features/snippets/public_snippets.feature deleted file mode 100644 index c2afb63b6d894917cb90be8fe5a18faa193420f3..0000000000000000000000000000000000000000 --- a/features/snippets/public_snippets.feature +++ /dev/null @@ -1,10 +0,0 @@ -Feature: Public snippets - Scenario: Unauthenticated user should see public snippets - Given There is public "Personal snippet one" snippet - And I visit snippet page "Personal snippet one" - Then I should see snippet "Personal snippet one" - - Scenario: Unauthenticated user should see raw public snippets - Given There is public "Personal snippet one" snippet - And I visit snippet raw page "Personal snippet one" - Then I should see raw snippet "Personal snippet one" diff --git a/features/snippets/snippets.feature b/features/snippets/snippets.feature deleted file mode 100644 index 6e8019c326fdbebd07598f4f360e9f124499dbb2..0000000000000000000000000000000000000000 --- a/features/snippets/snippets.feature +++ /dev/null @@ -1,28 +0,0 @@ -@snippets -Feature: Snippets - Background: - Given I sign in as a user - And I have public "Personal snippet one" snippet - And I have private "Personal snippet private" snippet - - Scenario: I create new snippet - Given I visit new snippet page - And I submit new snippet "Personal snippet three" - Then I should see snippet "Personal snippet three" - - Scenario: I update "Personal snippet one" - Given I visit snippet page "Personal snippet one" - And I click link "Edit" - And I submit new title "Personal snippet new title" - Then I should see "Personal snippet new title" - - Scenario: Set "Personal snippet one" public - Given I visit snippet page "Personal snippet one" - And I click link "Edit" - And I uncheck "Private" checkbox - Then I should see "Personal snippet one" public - - Scenario: I destroy "Personal snippet one" - Given I visit snippet page "Personal snippet one" - And I click link "Destroy" - Then I should not see "Personal snippet one" in snippets \ No newline at end of file diff --git a/features/snippets/user.feature b/features/snippets/user.feature deleted file mode 100644 index 5b5dadb7b399a332a8317e5fbc391c3551ffbf1b..0000000000000000000000000000000000000000 --- a/features/snippets/user.feature +++ /dev/null @@ -1,34 +0,0 @@ -@snippets -Feature: Snippets User - Background: - Given I sign in as a user - And I have public "Personal snippet one" snippet - And I have private "Personal snippet private" snippet - And I have internal "Personal snippet internal" snippet - - Scenario: I should see all my snippets - Given I visit my snippets page - Then I should see "Personal snippet one" in snippets - And I should see "Personal snippet private" in snippets - And I should see "Personal snippet internal" in snippets - - Scenario: I can see only my private snippets - Given I visit my snippets page - And I click "Private" filter - Then I should not see "Personal snippet one" in snippets - And I should not see "Personal snippet internal" in snippets - And I should see "Personal snippet private" in snippets - - Scenario: I can see only my public snippets - Given I visit my snippets page - And I click "Public" filter - Then I should see "Personal snippet one" in snippets - And I should not see "Personal snippet private" in snippets - And I should not see "Personal snippet internal" in snippets - - Scenario: I can see only my internal snippets - Given I visit my snippets page - And I click "Internal" filter - Then I should see "Personal snippet internal" in snippets - And I should not see "Personal snippet private" in snippets - And I should not see "Personal snippet one" in snippets diff --git a/features/steps/admin/active_tab.rb b/features/steps/admin/active_tab.rb deleted file mode 100644 index 90d13abdb1317356fa57fea0817d14eb44da5667..0000000000000000000000000000000000000000 --- a/features/steps/admin/active_tab.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Spinach::Features::AdminActiveTab < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedActiveTab - - step 'the active main tab should be Home' do - ensure_active_main_tab('Overview') - end - - step 'the active main tab should be Projects' do - ensure_active_main_tab('Projects') - end - - step 'the active main tab should be Groups' do - ensure_active_main_tab('Groups') - end - - step 'the active main tab should be Users' do - ensure_active_main_tab('Users') - end - - step 'the active main tab should be Logs' do - ensure_active_main_tab('Logs') - end - - step 'the active main tab should be Hooks' do - ensure_active_main_tab('Hooks') - end - - step 'the active main tab should be Resque' do - ensure_active_main_tab('Background Jobs') - end - - step 'the active main tab should be Messages' do - ensure_active_main_tab('Messages') - end -end diff --git a/features/steps/admin/applications.rb b/features/steps/admin/applications.rb deleted file mode 100644 index d59088fa3c32c815dc0f9aa0482bd2abd9762876..0000000000000000000000000000000000000000 --- a/features/steps/admin/applications.rb +++ /dev/null @@ -1,55 +0,0 @@ -class Spinach::Features::AdminApplications < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - step 'I click on new application button' do - click_on 'New Application' - end - - step 'I should see application form' do - page.should have_content "New application" - end - - step 'I fill application form out and submit' do - fill_in :doorkeeper_application_name, with: 'test' - fill_in :doorkeeper_application_redirect_uri, with: 'https://test.com' - click_on "Submit" - end - - step 'I see application' do - page.should have_content "Application: test" - page.should have_content "Application Id" - page.should have_content "Secret" - end - - step 'I click edit' do - click_on "Edit" - end - - step 'I see edit application form' do - page.should have_content "Edit application" - end - - step 'I change name of application and submit' do - page.should have_content "Edit application" - fill_in :doorkeeper_application_name, with: 'test_changed' - click_on "Submit" - end - - step 'I see that application was changed' do - page.should have_content "test_changed" - page.should have_content "Application Id" - page.should have_content "Secret" - end - - step 'I click to remove application' do - within '.oauth-applications' do - click_on "Destroy" - end - end - - step "I see that application is removed" do - page.find(".oauth-applications").should_not have_content "test_changed" - end -end diff --git a/features/steps/admin/broadcast_messages.rb b/features/steps/admin/broadcast_messages.rb deleted file mode 100644 index a35fa34a3a295e6d93fb14e3350ba41e95568af7..0000000000000000000000000000000000000000 --- a/features/steps/admin/broadcast_messages.rb +++ /dev/null @@ -1,41 +0,0 @@ -class Spinach::Features::AdminBroadcastMessages < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - step 'application already has admin messages' do - FactoryGirl.create(:broadcast_message, message: "Migration to new server") - end - - step 'I should be all broadcast messages' do - page.should have_content "Migration to new server" - end - - step 'submit form with new broadcast message' do - fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' - select '2018', from: "broadcast_message_ends_at_1i" - click_button "Add broadcast message" - end - - step 'I should be redirected to admin messages page' do - current_path.should == admin_broadcast_messages_path - end - - step 'I should see newly created broadcast message' do - page.should have_content 'Application update from 4:00 CST to 5:00 CST' - end - - step 'submit form with new customized broadcast message' do - fill_in 'broadcast_message_message', with: 'Application update from 4:00 CST to 5:00 CST' - click_link "Customize colors" - fill_in 'broadcast_message_color', with: '#f2dede' - fill_in 'broadcast_message_font', with: '#b94a48' - select '2018', from: "broadcast_message_ends_at_1i" - click_button "Add broadcast message" - end - - step 'I should see a customized broadcast message' do - page.should have_content 'Application update from 4:00 CST to 5:00 CST' - page.should have_selector %(div[style="background-color:#f2dede;color:#b94a48"]) - end -end diff --git a/features/steps/admin/deploy_keys.rb b/features/steps/admin/deploy_keys.rb deleted file mode 100644 index fb0b611762e6380368f8b0cdd6f12e0a232e776d..0000000000000000000000000000000000000000 --- a/features/steps/admin/deploy_keys.rb +++ /dev/null @@ -1,57 +0,0 @@ -class Spinach::Features::AdminDeployKeys < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - step 'there are public deploy keys in system' do - create(:deploy_key, public: true) - create(:another_deploy_key, public: true) - end - - step 'I should see all public deploy keys' do - DeployKey.are_public.each do |p| - page.should have_content p.title - end - end - - step 'I click on first deploy key' do - click_link DeployKey.are_public.first.title - end - - step 'I should see deploy key details' do - deploy_key = DeployKey.are_public.first - current_path.should == admin_deploy_key_path(deploy_key) - page.should have_content(deploy_key.title) - page.should have_content(deploy_key.key) - end - - step 'I visit admin deploy key page' do - visit admin_deploy_key_path(deploy_key) - end - - step 'I visit admin deploy keys page' do - visit admin_deploy_keys_path - end - - step 'I click \'New Deploy Key\'' do - click_link 'New Deploy Key' - end - - step 'I submit new deploy key' do - fill_in "deploy_key_title", with: "laptop" - fill_in "deploy_key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop" - click_button "Create" - end - - step 'I should be on admin deploy keys page' do - current_path.should == admin_deploy_keys_path - end - - step 'I should see newly created deploy key' do - page.should have_content(deploy_key.title) - end - - def deploy_key - @deploy_key ||= DeployKey.are_public.first - end -end diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb deleted file mode 100644 index 721460b93710f11b4df29fc7a5c213aaeadb6b3f..0000000000000000000000000000000000000000 --- a/features/steps/admin/groups.rb +++ /dev/null @@ -1,85 +0,0 @@ -class Spinach::Features::AdminGroups < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedUser - include SharedActiveTab - include Select2Helper - - When 'I visit admin group page' do - visit admin_group_path(current_group) - end - - When 'I click new group link' do - click_link "New Group" - end - - step 'I have group with projects' do - @group = create(:group) - @project = create(:project, group: @group) - @event = create(:closed_issue_event, project: @project) - - @project.team << [current_user, :master] - end - - step 'submit form with new group info' do - fill_in 'group_path', with: 'gitlab' - fill_in 'group_description', with: 'Group description' - click_button "Create group" - end - - step 'I should see newly created group' do - page.should have_content "Group: gitlab" - page.should have_content "Group description" - end - - step 'I should be redirected to group page' do - current_path.should == admin_group_path(Group.find_by(path: 'gitlab')) - end - - When 'I select user "John Doe" from user list as "Reporter"' do - select2(user_john.id, from: "#user_ids", multiple: true) - within "#new_project_member" do - select "Reporter", from: "access_level" - end - click_button "Add users to group" - end - - step 'I should see "John Doe" in team list in every project as "Reporter"' do - within ".group-users-list" do - page.should have_content "John Doe" - page.should have_content "Reporter" - end - end - - step 'I should be all groups' do - Group.all.each do |group| - page.should have_content group.name - end - end - - step 'we have user "John Doe" in group' do - current_group.add_user(user_john, Gitlab::Access::REPORTER) - end - - step 'I remove user "John Doe" from group' do - within "#user_#{user_john.id}" do - click_link 'Remove user from group' - end - end - - step 'I should not see "John Doe" in team list' do - within ".group-users-list" do - page.should_not have_content "John Doe" - end - end - - protected - - def current_group - @group ||= Group.first - end - - def user_john - @user_john ||= User.find_by(name: "John Doe") - end -end diff --git a/features/steps/admin/logs.rb b/features/steps/admin/logs.rb deleted file mode 100644 index 904e54686558337f876016f1c4ff1f8f73776e5a..0000000000000000000000000000000000000000 --- a/features/steps/admin/logs.rb +++ /dev/null @@ -1,11 +0,0 @@ -class Spinach::Features::AdminLogs < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - step 'I should see tabs with available logs' do - page.should have_content 'production.log' - page.should have_content 'githost.log' - page.should have_content 'application.log' - end -end diff --git a/features/steps/admin/projects.rb b/features/steps/admin/projects.rb deleted file mode 100644 index 9be4d39d2d5775bb5c75f33ebd49865fcc085394..0000000000000000000000000000000000000000 --- a/features/steps/admin/projects.rb +++ /dev/null @@ -1,48 +0,0 @@ -class Spinach::Features::AdminProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - step 'I should see all projects' do - Project.all.each do |p| - page.should have_content p.name_with_namespace - end - end - - step 'I click on first project' do - click_link Project.first.name_with_namespace - end - - step 'I should see project details' do - project = Project.first - current_path.should == admin_namespace_project_path(project.namespace, project) - page.should have_content(project.name_with_namespace) - page.should have_content(project.creator.name) - end - - step 'I visit admin project page' do - visit admin_namespace_project_path(project.namespace, project) - end - - step 'I transfer project to group \'Web\'' do - find(:xpath, "//input[@id='new_namespace_id']").set group.id - click_button 'Transfer' - end - - step 'group \'Web\'' do - create(:group, name: 'Web') - end - - step 'I should see project transfered' do - page.should have_content 'Web / ' + project.name - page.should have_content 'Namespace: Web' - end - - def project - @project ||= Project.first - end - - def group - Group.find_by(name: 'Web') - end -end diff --git a/features/steps/admin/settings.rb b/features/steps/admin/settings.rb deleted file mode 100644 index 87d4e969ff51ec1582b3c0b568d94cc59e19ec15..0000000000000000000000000000000000000000 --- a/features/steps/admin/settings.rb +++ /dev/null @@ -1,47 +0,0 @@ -class Spinach::Features::AdminSettings < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - include Gitlab::CurrentSettings - - step 'I modify settings and save form' do - uncheck 'Gravatar enabled' - fill_in 'Home page url', with: 'https://about.gitlab.com/' - click_button 'Save' - end - - step 'I should see application settings saved' do - current_application_settings.gravatar_enabled.should be_false - current_application_settings.home_page_url.should == 'https://about.gitlab.com/' - page.should have_content 'Application settings saved successfully' - end - - step 'I click on "Service Templates"' do - click_link 'Service Templates' - end - - step 'I click on "Slack" service' do - click_link 'Slack' - end - - step 'I check all events and submit form' do - page.check('Active') - page.check('Push events') - page.check('Tag push events') - page.check('Comments') - page.check('Issues events') - page.check('Merge Request events') - fill_in 'Webhook', with: "http://localhost" - click_on 'Save' - end - - step 'I should see service template settings saved' do - page.should have_content 'Application settings saved successfully' - end - - step 'I should see all checkboxes checked' do - all('input[type=checkbox]').each do |checkbox| - checkbox.should be_checked - end - end -end diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb deleted file mode 100644 index e13830972487e0e4c99e1b94a806ca9d29900793..0000000000000000000000000000000000000000 --- a/features/steps/admin/users.rb +++ /dev/null @@ -1,117 +0,0 @@ -class Spinach::Features::AdminUsers < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedAdmin - - step 'I should see all users' do - User.all.each do |user| - page.should have_content user.name - end - end - - step 'Click edit' do - @user = User.first - find("#edit_user_#{@user.id}").click - end - - step 'Input non ascii char in username' do - fill_in 'user_username', with: "\u3042\u3044" - end - - step 'Click save' do - click_button("Save") - end - - step 'See username error message' do - within "#error_explanation" do - page.should have_content "Username" - end - end - - step 'Not changed form action url' do - page.should have_selector %(form[action="/admin/users/#{@user.username}"]) - end - - step 'I submit modified user' do - check :user_can_create_group - click_button 'Save' - end - - step 'I see user attributes changed' do - page.should have_content 'Can create groups: Yes' - end - - step 'click edit on my user' do - find("#edit_user_#{current_user.id}").click - end - - step 'I view the user with secondary email' do - @user_with_secondary_email = User.last - @user_with_secondary_email.emails.new(email: "secondary@example.com") - @user_with_secondary_email.save - visit "/admin/users/#{@user_with_secondary_email.username}" - end - - step 'I see the secondary email' do - page.should have_content "Secondary email: #{@user_with_secondary_email.emails.last.email}" - end - - step 'I click remove secondary email' do - find("#remove_email_#{@user_with_secondary_email.emails.last.id}").click - end - - step 'I should not see secondary email anymore' do - page.should_not have_content "Secondary email:" - end - - step 'user "Mike" with groups and projects' do - user = create(:user, name: 'Mike') - - project = create(:empty_project) - project.team << [user, :developer] - - group = create(:group) - group.add_user(user, Gitlab::Access::DEVELOPER) - end - - step 'click on "Mike" link' do - click_link "Mike" - end - - step 'I should see user "Mike" details' do - page.should have_content 'Account' - page.should have_content 'Personal projects limit' - end - - step 'user "Pete" with ssh keys' do - user = create(:user, name: 'Pete') - create(:key, user: user, title: "ssh-rsa Key1", key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4FIEBXGi4bPU8kzxMefudPIJ08/gNprdNTaO9BR/ndy3+58s2HCTw2xCHcsuBmq+TsAqgEidVq4skpqoTMB+Uot5Uzp9z4764rc48dZiI661izoREoKnuRQSsRqUTHg5wrLzwxlQbl1MVfRWQpqiz/5KjBC7yLEb9AbusjnWBk8wvC1bQPQ1uLAauEA7d836tgaIsym9BrLsMVnR4P1boWD3Xp1B1T/ImJwAGHvRmP/ycIqmKdSpMdJXwxcb40efWVj0Ibbe7ii9eeoLdHACqevUZi6fwfbymdow+FeqlkPoHyGg3Cu4vD/D8+8cRc7mE/zGCWcQ15Var83Tczour Key1") - create(:key, user: user, title: "ssh-rsa Key2", key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQSTWXhJAX/He+nG78MiRRRn7m0Pb0XbcgTxE0etArgoFoh9WtvDf36HG6tOSg/0UUNcp0dICsNAmhBKdncp6cIyPaXJTURPRAGvhI0/VDk4bi27bRnccGbJ/hDaUxZMLhhrzY0r22mjVf8PF6dvv5QUIQVm1/LeaWYsHHvLgiIjwrXirUZPnFrZw6VLREoBKG8uWvfSXw1L5eapmstqfsME8099oi+vWLR8MgEysZQmD28M73fgW4zek6LDQzKQyJx9nB+hJkKUDvcuziZjGmRFlNgSA2mguERwL1OXonD8WYUrBDGKroIvBT39zS5d9tQDnidEJZ9Y8gv5ViYP7x Key2") - end - - step 'click on user "Pete"' do - click_link 'Pete' - end - - step 'I should see key list' do - page.should have_content 'ssh-rsa Key2' - page.should have_content 'ssh-rsa Key1' - end - - step 'I click on the key title' do - click_link 'ssh-rsa Key2' - end - - step 'I should see key details' do - page.should have_content 'ssh-rsa Key2' - page.should have_content 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQSTWXhJAX/He+nG78MiRRRn7m0Pb0XbcgTxE0etArgoFoh9WtvDf36HG6tOSg/0UUNcp0dICsNAmhBKdncp6cIyPaXJTURPRAGvhI0/VDk4bi27bRnccGbJ/hDaUxZMLhhrzY0r22mjVf8PF6dvv5QUIQVm1/LeaWYsHHvLgiIjwrXirUZPnFrZw6VLREoBKG8uWvfSXw1L5eapmstqfsME8099oi+vWLR8MgEysZQmD28M73fgW4zek6LDQzKQyJx9nB+hJkKUDvcuziZjGmRFlNgSA2mguERwL1OXonD8WYUrBDGKroIvBT39zS5d9tQDnidEJZ9Y8gv5ViYP7x Key2' - end - - step 'I click on remove key' do - click_link 'Remove' - end - - step 'I should see the key removed' do - page.should_not have_content 'ssh-rsa Key2' - end -end diff --git a/features/steps/dashboard/active_tab.rb b/features/steps/dashboard/active_tab.rb deleted file mode 100644 index 0e2c04fb29994cfe645c9fc31b99e13092673a6f..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/active_tab.rb +++ /dev/null @@ -1,9 +0,0 @@ -class Spinach::Features::DashboardActiveTab < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedActiveTab - - step 'the active main tab should be Help' do - ensure_active_main_tab('Help') - end -end diff --git a/features/steps/dashboard/archived_projects.rb b/features/steps/dashboard/archived_projects.rb deleted file mode 100644 index 969baf92287c620cfdd74bfdd1f157e6d9046518..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/archived_projects.rb +++ /dev/null @@ -1,22 +0,0 @@ -class Spinach::Features::DashboardArchivedProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - When 'project "Forum" is archived' do - project = Project.find_by(name: "Forum") - project.update_attribute(:archived, true) - end - - step 'I should see "Shop" project link' do - page.should have_link "Shop" - end - - step 'I should not see "Forum" project link' do - page.should_not have_link "Forum" - end - - step 'I should see "Forum" project link' do - page.should have_link "Forum" - end -end diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb deleted file mode 100644 index 8508b2a8096f04baaeda21bd2fbd36f25f98306a..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/dashboard.rb +++ /dev/null @@ -1,85 +0,0 @@ -class Spinach::Features::Dashboard < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I should see "New Project" link' do - page.should have_link "New project" - end - - step 'I should see "Shop" project link' do - page.should have_link "Shop" - end - - step 'I should see last push widget' do - page.should have_content "You pushed to fix" - page.should have_link "Create Merge Request" - end - - step 'I click "Create Merge Request" link' do - click_link "Create Merge Request" - end - - step 'I see prefilled new Merge Request page' do - current_path.should == new_namespace_project_merge_request_path(@project.namespace, @project) - find("#merge_request_target_project_id").value.should == @project.id.to_s - find("#merge_request_source_branch").value.should == "fix" - find("#merge_request_target_branch").value.should == "master" - end - - step 'user with name "John Doe" joined project "Shop"' do - user = create(:user, {name: "John Doe"}) - project.team << [user, :master] - Event.create( - project: project, - author_id: user.id, - action: Event::JOINED - ) - end - - step 'I should see "John Doe joined project Shop" event' do - page.should have_content "John Doe joined project #{project.name_with_namespace}" - end - - step 'user with name "John Doe" left project "Shop"' do - user = User.find_by(name: "John Doe") - Event.create( - project: project, - author_id: user.id, - action: Event::LEFT - ) - end - - step 'I should see "John Doe left project Shop" event' do - page.should have_content "John Doe left project #{project.name_with_namespace}" - end - - step 'I have group with projects' do - @group = create(:group) - @project = create(:project, namespace: @group) - @event = create(:closed_issue_event, project: @project) - - @project.team << [current_user, :master] - end - - step 'I should see projects list' do - @user.authorized_projects.all.each do |project| - page.should have_link project.name_with_namespace - end - end - - step 'I should see groups list' do - Group.all.each do |group| - page.should have_link group.name - end - end - - step 'group has a projects that does not belongs to me' do - @forbidden_project1 = create(:project, group: @group) - @forbidden_project2 = create(:project, group: @group) - end - - step 'I should see 1 project at group list' do - find('span.last_activity/span').should have_content('1') - end -end diff --git a/features/steps/dashboard/event_filters.rb b/features/steps/dashboard/event_filters.rb deleted file mode 100644 index 3da3d62d0c0468efd690c33513ef0fb9829034ac..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/event_filters.rb +++ /dev/null @@ -1,85 +0,0 @@ -class Spinach::Features::EventFilters < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I should see push event' do - page.should have_selector('span.pushed') - end - - step 'I should not see push event' do - page.should_not have_selector('span.pushed') - end - - step 'I should see new member event' do - page.should have_selector('span.joined') - end - - step 'I should not see new member event' do - page.should_not have_selector('span.joined') - end - - step 'I should see merge request event' do - page.should have_selector('span.accepted') - end - - step 'I should not see merge request event' do - page.should_not have_selector('span.accepted') - end - - step 'this project has push event' do - data = { - before: Gitlab::Git::BLANK_SHA, - after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", - ref: "refs/heads/new_design", - user_id: @user.id, - user_name: @user.name, - repository: { - name: @project.name, - url: "localhost/rubinius", - description: "", - homepage: "localhost/rubinius", - private: true - } - } - - @event = Event.create( - project: @project, - action: Event::PUSHED, - data: data, - author_id: @user.id - ) - end - - step 'this project has new member event' do - user = create(:user, {name: "John Doe"}) - Event.create( - project: @project, - author_id: user.id, - action: Event::JOINED - ) - end - - step 'this project has merge request event' do - merge_request = create :merge_request, author: @user, source_project: @project, target_project: @project - Event.create( - project: @project, - action: Event::MERGED, - target_id: merge_request.id, - target_type: "MergeRequest", - author_id: @user.id - ) - end - - When 'I click "push" event filter' do - click_link("push_event_filter") - end - - When 'I click "team" event filter' do - click_link("team_event_filter") - end - - When 'I click "merge" event filter' do - click_link("merged_event_filter") - end -end diff --git a/features/steps/dashboard/group.rb b/features/steps/dashboard/group.rb deleted file mode 100644 index 8384df2fb59cb15aaaf0dd83d03a80670492645a..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/group.rb +++ /dev/null @@ -1,63 +0,0 @@ -class Spinach::Features::DashboardGroup < Spinach::FeatureSteps - include SharedAuthentication - include SharedGroup - include SharedPaths - include SharedUser - - # Leave - - step 'I click on the "Leave" button for group "Owned"' do - find(:css, 'li', text: "Owner").find(:css, 'i.fa.fa-sign-out').click - # poltergeist always confirms popups. - end - - step 'I click on the "Leave" button for group "Guest"' do - find(:css, 'li', text: "Guest").find(:css, 'i.fa.fa-sign-out').click - # poltergeist always confirms popups. - end - - step 'I should not see the "Leave" button for group "Owned"' do - find(:css, 'li', text: "Owner").should_not have_selector(:css, 'i.fa.fa-sign-out') - # poltergeist always confirms popups. - end - - step 'I should not see the "Leave" button for groupr "Guest"' do - find(:css, 'li', text: "Guest").should_not have_selector(:css, 'i.fa.fa-sign-out') - # poltergeist always confirms popups. - end - - step 'I should see group "Owned" in group list' do - page.should have_content("Owned") - end - - step 'I should not see group "Owned" in group list' do - page.should_not have_content("Owned") - end - - step 'I should see group "Guest" in group list' do - page.should have_content("Guest") - end - - step 'I should not see group "Guest" in group list' do - page.should_not have_content("Guest") - end - - step 'I click new group link' do - click_link "New Group" - end - - step 'submit form with new group "Samurai" info' do - fill_in 'group_path', with: 'Samurai' - fill_in 'group_description', with: 'Tokugawa Shogunate' - click_button "Create group" - end - - step 'I should be redirected to group "Samurai" page' do - current_path.should == group_path(Group.find_by(name: 'Samurai')) - end - - step 'I should see newly created group "Samurai"' do - page.should have_content "Samurai" - page.should have_content "Tokugawa Shogunate" - end -end diff --git a/features/steps/dashboard/issues.rb b/features/steps/dashboard/issues.rb deleted file mode 100644 index 60da36e86de10928faac3d51788440c6b258ba0a..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/issues.rb +++ /dev/null @@ -1,83 +0,0 @@ -class Spinach::Features::DashboardIssues < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include Select2Helper - - step 'I should see issues assigned to me' do - should_see(assigned_issue) - should_not_see(authored_issue) - should_not_see(other_issue) - end - - step 'I should see issues authored by me' do - should_see(authored_issue) - should_see(authored_issue_on_public_project) - should_not_see(assigned_issue) - should_not_see(other_issue) - end - - step 'I should see all issues' do - should_see(authored_issue) - should_see(assigned_issue) - should_see(other_issue) - end - - step 'I have authored issues' do - authored_issue - authored_issue_on_public_project - end - - step 'I have assigned issues' do - assigned_issue - end - - step 'I have other issues' do - other_issue - end - - step 'I click "Authored by me" link' do - select2(current_user.id, from: "#author_id") - select2(nil, from: "#assignee_id") - end - - step 'I click "All" link' do - select2(nil, from: "#author_id") - select2(nil, from: "#assignee_id") - end - - def should_see(issue) - page.should have_content(issue.title[0..10]) - end - - def should_not_see(issue) - page.should_not have_content(issue.title[0..10]) - end - - def assigned_issue - @assigned_issue ||= create :issue, assignee: current_user, project: project - end - - def authored_issue - @authored_issue ||= create :issue, author: current_user, project: project - end - - def other_issue - @other_issue ||= create :issue, project: project - end - - def authored_issue_on_public_project - @authored_issue_on_public_project ||= create :issue, author: current_user, project: public_project - end - - def project - @project ||= begin - project =create :project - project.team << [current_user, :master] - project - end - end - - def public_project - @public_project ||= create :project, :public - end -end diff --git a/features/steps/dashboard/merge_requests.rb b/features/steps/dashboard/merge_requests.rb deleted file mode 100644 index 9d92082bb83d5aa32b654558e1dc2e57ccda17bc..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/merge_requests.rb +++ /dev/null @@ -1,113 +0,0 @@ -class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include Select2Helper - - step 'I should see merge requests assigned to me' do - should_see(assigned_merge_request) - should_see(assigned_merge_request_from_fork) - should_not_see(authored_merge_request) - should_not_see(authored_merge_request_from_fork) - should_not_see(other_merge_request) - end - - step 'I should see merge requests authored by me' do - should_see(authored_merge_request) - should_see(authored_merge_request_from_fork) - should_not_see(assigned_merge_request) - should_not_see(assigned_merge_request_from_fork) - should_not_see(other_merge_request) - end - - step 'I should see all merge requests' do - should_see(authored_merge_request) - should_see(assigned_merge_request) - should_see(other_merge_request) - end - - step 'I have authored merge requests' do - authored_merge_request - authored_merge_request_from_fork - end - - step 'I have assigned merge requests' do - assigned_merge_request - assigned_merge_request_from_fork - end - - step 'I have other merge requests' do - other_merge_request - end - - step 'I click "Authored by me" link' do - select2(current_user.id, from: "#author_id") - select2(nil, from: "#assignee_id") - end - - step 'I click "All" link' do - select2(nil, from: "#author_id") - select2(nil, from: "#assignee_id") - end - - def should_see(merge_request) - page.should have_content(merge_request.title[0..10]) - end - - def should_not_see(merge_request) - page.should_not have_content(merge_request.title[0..10]) - end - - def assigned_merge_request - @assigned_merge_request ||= create :merge_request, - assignee: current_user, - target_project: project, - source_project: project - end - - def authored_merge_request - @authored_merge_request ||= create :merge_request, - source_branch: 'simple_merge_request', - author: current_user, - target_project: project, - source_project: project - end - - def other_merge_request - @other_merge_request ||= create :merge_request, - source_branch: '2_3_notes_fix', - target_project: project, - source_project: project - end - - def authored_merge_request_from_fork - @authored_merge_request_from_fork ||= create :merge_request, - source_branch: 'basic_page', - author: current_user, - target_project: public_project, - source_project: forked_project - end - - def assigned_merge_request_from_fork - @assigned_merge_request_from_fork ||= create :merge_request, - source_branch: 'basic_page_fix', - assignee: current_user, - target_project: public_project, - source_project: forked_project - end - - def project - @project ||= begin - project =create :project - project.team << [current_user, :master] - project - end - end - - def public_project - @public_project ||= create :project, :public - end - - def forked_project - @forked_project ||= Projects::ForkService.new(public_project, current_user).execute - end -end diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb deleted file mode 100644 index 5e588ceb780c7f4196ad2702a0adbf6b81370662..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/new_project.rb +++ /dev/null @@ -1,27 +0,0 @@ -class Spinach::Features::NewProject < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I click "New project" link' do - click_link "New project" - end - - step 'I see "New project" page' do - page.should have_content("Project path") - end - - step 'I click on "Import project from GitHub"' do - first('.how_to_import_link').click - end - - step 'I see instructions on how to import from GitHub' do - github_modal = first('.modal-body') - github_modal.should be_visible - github_modal.should have_content "To enable importing projects from GitHub" - - all('.modal-body').each do |element| - element.should_not be_visible unless element == github_modal - end - end -end diff --git a/features/steps/dashboard/shortcuts.rb b/features/steps/dashboard/shortcuts.rb deleted file mode 100644 index a9083850b523fca2a0c0a0ab07ba3ab0fa82559d..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/shortcuts.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Spinach::Features::DashboardShortcuts < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - include SharedActiveTab -end diff --git a/features/steps/dashboard/starred_projects.rb b/features/steps/dashboard/starred_projects.rb deleted file mode 100644 index b9ad2f13e293248e55a4307aeb2619a723093da1..0000000000000000000000000000000000000000 --- a/features/steps/dashboard/starred_projects.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Spinach::Features::DashboardStarredProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I starred project "Community"' do - current_user.toggle_star(Project.find_by(name: 'Community')) - end - - step 'I should not see project "Shop"' do - within 'aside' do - page.should_not have_content('Shop') - end - end -end diff --git a/features/steps/explore/groups.rb b/features/steps/explore/groups.rb deleted file mode 100644 index 0c2127d4c4b3ba7133c1fdb68bf9d2fec1713dd8..0000000000000000000000000000000000000000 --- a/features/steps/explore/groups.rb +++ /dev/null @@ -1,92 +0,0 @@ -class Spinach::Features::ExploreGroups < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedGroup - include SharedProject - - step 'group "TestGroup" has private project "Enterprise"' do - group_has_project("TestGroup", "Enterprise", Gitlab::VisibilityLevel::PRIVATE) - end - - step 'group "TestGroup" has internal project "Internal"' do - group_has_project("TestGroup", "Internal", Gitlab::VisibilityLevel::INTERNAL) - end - - step 'group "TestGroup" has public project "Community"' do - group_has_project("TestGroup", "Community", Gitlab::VisibilityLevel::PUBLIC) - end - - step '"John Doe" is owner of group "TestGroup"' do - group = Group.find_by(name: "TestGroup") || create(:group, name: "TestGroup") - user = create(:user, name: "John Doe") - group.add_user(user, Gitlab::Access::OWNER) - end - - step 'I visit group "TestGroup" page' do - visit group_path(Group.find_by(name: "TestGroup")) - end - - step 'I visit group "TestGroup" issues page' do - visit issues_group_path(Group.find_by(name: "TestGroup")) - end - - step 'I visit group "TestGroup" merge requests page' do - visit merge_requests_group_path(Group.find_by(name: "TestGroup")) - end - - step 'I visit group "TestGroup" members page' do - visit group_group_members_path(Group.find_by(name: "TestGroup")) - end - - step 'I should not see project "Enterprise" items' do - page.should_not have_content "Enterprise" - end - - step 'I should see project "Internal" items' do - page.should have_content "Internal" - end - - step 'I should not see project "Internal" items' do - page.should_not have_content "Internal" - end - - step 'I should see project "Community" items' do - page.should have_content "Community" - end - - step 'I change filter to Everyone\'s' do - click_link "Everyone's" - end - - step 'I should see group member "John Doe"' do - page.should have_content "John Doe" - end - - step 'I should not see member roles' do - body.should_not match(%r{owner|developer|reporter|guest}i) - end - - protected - - def group_has_project(groupname, projectname, visibility_level) - group = Group.find_by(name: groupname) || create(:group, name: groupname) - project = create(:project, - namespace: group, - name: projectname, - path: "#{groupname}-#{projectname}", - visibility_level: visibility_level - ) - create(:issue, - title: "#{projectname} feature", - project: project - ) - create(:merge_request, - title: "#{projectname} feature implemented", - source_project: project, - target_project: project - ) - create(:closed_issue_event, - project: project - ) - end -end diff --git a/features/steps/explore/projects.rb b/features/steps/explore/projects.rb deleted file mode 100644 index 26b71406bd8a9a52756a0f6fff4af0214a7f0412..0000000000000000000000000000000000000000 --- a/features/steps/explore/projects.rb +++ /dev/null @@ -1,148 +0,0 @@ -class Spinach::Features::ExploreProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I should see project "Empty Public Project"' do - page.should have_content "Empty Public Project" - end - - step 'I should see public project details' do - page.should have_content '32 branches' - page.should have_content '16 tags' - end - - step 'I should see project readme' do - page.should have_content 'README.md' - end - - step 'I should see empty public project details' do - page.should have_content 'Git global setup' - end - - step 'I should see empty public project details with http clone info' do - project = Project.find_by(name: 'Empty Public Project') - all(:css, '.git-empty .clone').each do |element| - element.text.should include(project.http_url_to_repo) - end - end - - step 'I should see empty public project details with ssh clone info' do - project = Project.find_by(name: 'Empty Public Project') - all(:css, '.git-empty .clone').each do |element| - element.text.should include(project.url_to_repo) - end - end - - step 'I should see project "Community" home page' do - within '.navbar-gitlab .title' do - page.should have_content 'Community' - end - end - - step 'I should see project "Internal" home page' do - within '.navbar-gitlab .title' do - page.should have_content 'Internal' - end - end - - step 'I should see an http link to the repository' do - project = Project.find_by(name: 'Community') - page.should have_field('project_clone', with: project.http_url_to_repo) - end - - step 'I should see an ssh link to the repository' do - project = Project.find_by(name: 'Community') - page.should have_field('project_clone', with: project.url_to_repo) - end - - step 'I visit "Community" issues page' do - create(:issue, - title: "Bug", - project: public_project - ) - create(:issue, - title: "New feature", - project: public_project - ) - visit namespace_project_issues_path(public_project.namespace, public_project) - end - - - step 'I should see list of issues for "Community" project' do - page.should have_content "Bug" - page.should have_content public_project.name - page.should have_content "New feature" - end - - step 'I visit "Internal" issues page' do - create(:issue, - title: "Internal Bug", - project: internal_project - ) - create(:issue, - title: "New internal feature", - project: internal_project - ) - visit namespace_project_issues_path(internal_project.namespace, internal_project) - end - - - step 'I should see list of issues for "Internal" project' do - page.should have_content "Internal Bug" - page.should have_content internal_project.name - page.should have_content "New internal feature" - end - - step 'I visit "Community" merge requests page' do - visit namespace_project_merge_requests_path(public_project.namespace, public_project) - end - - step 'project "Community" has "Bug fix" open merge request' do - create(:merge_request, - title: "Bug fix for public project", - source_project: public_project, - target_project: public_project, - ) - end - - step 'I should see list of merge requests for "Community" project' do - page.should have_content public_project.name - page.should have_content public_merge_request.source_project.name - end - - step 'I visit "Internal" merge requests page' do - visit namespace_project_merge_requests_path(internal_project.namespace, internal_project) - end - - step 'project "Internal" has "Feature implemented" open merge request' do - create(:merge_request, - title: "Feature implemented", - source_project: internal_project, - target_project: internal_project - ) - end - - step 'I should see list of merge requests for "Internal" project' do - page.should have_content internal_project.name - page.should have_content internal_merge_request.source_project.name - end - - def internal_project - @internal_project ||= Project.find_by!(name: 'Internal') - end - - def public_project - @public_project ||= Project.find_by!(name: 'Community') - end - - - def internal_merge_request - @internal_merge_request ||= MergeRequest.find_by!(title: 'Feature implemented') - end - - def public_merge_request - @public_merge_request ||= MergeRequest.find_by!(title: 'Bug fix for public project') - end -end - diff --git a/features/steps/groups.rb b/features/steps/groups.rb deleted file mode 100644 index 228b83e5fd0a61e58d2dbb95cb2ea5d67b1722f9..0000000000000000000000000000000000000000 --- a/features/steps/groups.rb +++ /dev/null @@ -1,300 +0,0 @@ -class Spinach::Features::Groups < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedGroup - include SharedUser - include Select2Helper - - step 'gitlab user "Mike"' do - create(:user, name: "Mike") - end - - step 'I click link "Add members"' do - find(:css, 'button.btn-new').click - end - - step 'I select "Mike" as "Reporter"' do - user = User.find_by(name: "Mike") - - within ".users-group-form" do - select2(user.id, from: "#user_ids", multiple: true) - select "Reporter", from: "access_level" - end - - click_button "Add users to group" - end - - step 'I should see "Mike" in team list as "Reporter"' do - within '.well-list' do - page.should have_content('Mike') - page.should have_content('Reporter') - end - end - - step 'I select "sjobs@apple.com" as "Reporter"' do - within ".users-group-form" do - select2("sjobs@apple.com", from: "#user_ids", multiple: true) - select "Reporter", from: "access_level" - end - - click_button "Add users to group" - end - - step 'I should see "sjobs@apple.com" in team list as invited "Reporter"' do - within '.well-list' do - page.should have_content('sjobs@apple.com') - page.should have_content('invited') - page.should have_content('Reporter') - end - end - - step 'I should see group "Owned" projects list' do - Group.find_by(name: "Owned").projects.each do |project| - page.should have_link project.name - end - end - - step 'I should see projects activity feed' do - page.should have_content 'closed issue' - end - - step 'I should see issues from group "Owned" assigned to me' do - assigned_to_me(:issues).each do |issue| - page.should have_content issue.title - end - end - - step 'I should see merge requests from group "Owned" assigned to me' do - assigned_to_me(:merge_requests).each do |issue| - page.should have_content issue.title[0..80] - end - end - - step 'I select user "Mary Jane" from list with role "Reporter"' do - user = User.find_by(name: "Mary Jane") || create(:user, name: "Mary Jane") - click_button 'Add members' - within ".users-group-form" do - select2(user.id, from: "#user_ids", multiple: true) - select "Reporter", from: "access_level" - end - click_button "Add users to group" - end - - step 'I should see user "John Doe" in team list' do - projects_with_access = find(".panel .well-list") - projects_with_access.should have_content("John Doe") - end - - step 'I should not see user "John Doe" in team list' do - projects_with_access = find(".panel .well-list") - projects_with_access.should_not have_content("John Doe") - end - - step 'I should see user "Mary Jane" in team list' do - projects_with_access = find(".panel .well-list") - projects_with_access.should have_content("Mary Jane") - end - - step 'I should not see user "Mary Jane" in team list' do - projects_with_access = find(".panel .well-list") - projects_with_access.should_not have_content("Mary Jane") - end - - step 'project from group "Owned" has issues assigned to me' do - create :issue, - project: project, - assignee: current_user, - author: current_user - end - - step 'project from group "Owned" has merge requests assigned to me' do - create :merge_request, - source_project: project, - target_project: project, - assignee: current_user, - author: current_user - end - - step 'I change group "Owned" name to "new-name"' do - fill_in 'group_name', with: 'new-name' - fill_in 'group_path', with: 'new-name' - click_button "Save group" - end - - step 'I should see new group "Owned" name' do - within ".navbar-gitlab" do - page.should have_content "new-name" - end - end - - step 'I change group "Owned" avatar' do - attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png')) - click_button "Save group" - Group.find_by(name: "Owned").reload - end - - step 'I should see new group "Owned" avatar' do - Group.find_by(name: "Owned").avatar.should be_instance_of AvatarUploader - Group.find_by(name: "Owned").avatar.url.should == "/uploads/group/avatar/#{ Group.find_by(name:"Owned").id }/gitlab_logo.png" - end - - step 'I should see the "Remove avatar" button' do - page.should have_link("Remove avatar") - end - - step 'I have group "Owned" avatar' do - attach_file(:group_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png')) - click_button "Save group" - Group.find_by(name: "Owned").reload - end - - step 'I remove group "Owned" avatar' do - click_link "Remove avatar" - Group.find_by(name: "Owned").reload - end - - step 'I should not see group "Owned" avatar' do - Group.find_by(name: "Owned").avatar?.should be_false - end - - step 'I should not see the "Remove avatar" button' do - page.should_not have_link("Remove avatar") - end - - step 'I click on the "Remove User From Group" button for "John Doe"' do - find(:css, 'li', text: "John Doe").find(:css, 'a.btn-remove').click - # poltergeist always confirms popups. - end - - step 'I click on the "Remove User From Group" button for "Mary Jane"' do - find(:css, 'li', text: "Mary Jane").find(:css, 'a.btn-remove').click - # poltergeist always confirms popups. - end - - step 'I should not see the "Remove User From Group" button for "John Doe"' do - find(:css, 'li', text: "John Doe").should_not have_selector(:css, 'a.btn-remove') - # poltergeist always confirms popups. - end - - step 'I should not see the "Remove User From Group" button for "Mary Jane"' do - find(:css, 'li', text: "Mary Jane").should_not have_selector(:css, 'a.btn-remove') - # poltergeist always confirms popups. - end - - step 'I search for \'Mary\' member' do - within '.member-search-form' do - fill_in 'search', with: 'Mary' - click_button 'Search' - end - end - - step 'I click on group milestones' do - click_link 'Milestones' - end - - step 'I should see group milestones index page has no milestones' do - page.should have_content('No milestones to show') - end - - step 'Group has projects with milestones' do - group_milestone - end - - step 'I should see group milestones index page with milestones' do - page.should have_content('Version 7.2') - page.should have_content('GL-113') - page.should have_link('2 Issues', href: group_milestone_path("owned", "version-7-2", title: "Version 7.2")) - page.should have_link('3 Merge Requests', href: group_milestone_path("owned", "gl-113", title: "GL-113")) - end - - step 'I click on one group milestone' do - click_link 'GL-113' - end - - step 'I should see group milestone with descriptions and expiry date' do - page.should have_content('expires at Aug 20, 2114') - end - - step 'I should see group milestone with all issues and MRs assigned to that milestone' do - page.should have_content('Milestone GL-113') - page.should have_content('Progress: 0 closed – 4 open') - page.should have_link(@issue1.title, href: namespace_project_issue_path(@project1.namespace, @project1, @issue1)) - page.should have_link(@mr3.title, href: namespace_project_merge_request_path(@project3.namespace, @project3, @mr3)) - end - - protected - - def assigned_to_me(key) - project.send(key).where(assignee_id: current_user.id) - end - - def project - Group.find_by(name: "Owned").projects.first - end - - def group_milestone - group = Group.find_by(name: "Owned") - - @project1 = create :project, - group: group - project2 = create :project, - path: 'gitlab-ci', - group: group - @project3 = create :project, - path: 'cookbook-gitlab', - group: group - milestone1_project1 = create :milestone, - title: "Version 7.2", - project: @project1 - milestone1_project2 = create :milestone, - title: "Version 7.2", - project: project2 - milestone1_project3 = create :milestone, - title: "Version 7.2", - project: @project3 - milestone2_project1 = create :milestone, - title: "GL-113", - project: @project1 - milestone2_project2 = create :milestone, - title: "GL-113", - project: project2 - milestone2_project3 = create :milestone, - title: "GL-113", - project: @project3, - due_date: '2114-08-20', - description: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry' - @issue1 = create :issue, - project: @project1, - assignee: current_user, - author: current_user, - milestone: milestone2_project1 - issue2 = create :issue, - project: project2, - assignee: current_user, - author: current_user, - milestone: milestone1_project2 - issue3 = create :issue, - project: @project3, - assignee: current_user, - author: current_user, - milestone: milestone1_project1 - mr1 = create :merge_request, - source_project: @project1, - target_project: @project1, - assignee: current_user, - author: current_user, - milestone: milestone2_project1 - mr2 = create :merge_request, - source_project: project2, - target_project: project2, - assignee: current_user, - author: current_user, - milestone: milestone2_project2 - @mr3 = create :merge_request, - source_project: @project3, - target_project: @project3, - assignee: current_user, - author: current_user, - milestone: milestone2_project3 - end -end diff --git a/features/steps/invites.rb b/features/steps/invites.rb deleted file mode 100644 index d051cc3edc8b0bf69ab9ebe1a1b35dc06740a50e..0000000000000000000000000000000000000000 --- a/features/steps/invites.rb +++ /dev/null @@ -1,80 +0,0 @@ -class Spinach::Features::Invites < Spinach::FeatureSteps - include SharedAuthentication - include SharedUser - include SharedGroup - - step '"John Doe" has invited "user@example.com" to group "Owned"' do - user = User.find_by(name: "John Doe") - group = Group.find_by(name: "Owned") - group.add_user("user@example.com", Gitlab::Access::DEVELOPER, user) - end - - step 'I visit the invitation page' do - group = Group.find_by(name: "Owned") - invite = group.group_members.invite.last - invite.generate_invite_token! - @raw_invite_token = invite.raw_invite_token - visit invite_path(@raw_invite_token) - end - - step 'I should be redirected to the sign in page' do - expect(current_path).to eq(new_user_session_path) - end - - step 'I should see a notice telling me to sign in' do - expect(page).to have_content "To accept this invitation, sign in" - end - - step 'I should be redirected to the invitation page' do - expect(current_path).to eq(invite_path(@raw_invite_token)) - end - - step 'I should see the invitation details' do - expect(page).to have_content("You have been invited by John Doe to join group Owned as Developer.") - end - - step "I should see a message telling me I'm already a member" do - expect(page).to have_content("However, you are already a member of this group.") - end - - step 'I should see an "Accept invitation" button' do - expect(page).to have_link("Accept invitation") - end - - step 'I should see a "Decline" button' do - expect(page).to have_link("Decline") - end - - step 'I click the "Accept invitation" button' do - page.click_link "Accept invitation" - end - - step 'I should be redirected to the group page' do - group = Group.find_by(name: "Owned") - expect(current_path).to eq(group_path(group)) - end - - step 'I should see a notice telling me I have access' do - expect(page).to have_content("You have been granted Developer access to group Owned.") - end - - step 'I click the "Decline" button' do - page.click_link "Decline" - end - - step 'I should be redirected to the dashboard' do - expect(current_path).to eq(dashboard_path) - end - - step 'I should see a notice telling me I have declined' do - expect(page).to have_content("You have declined the invitation to join group Owned.") - end - - step "I visit the invitation's decline page" do - group = Group.find_by(name: "Owned") - invite = group.group_members.invite.last - invite.generate_invite_token! - @raw_invite_token = invite.raw_invite_token - visit decline_invite_path(@raw_invite_token) - end -end diff --git a/features/steps/profile/active_tab.rb b/features/steps/profile/active_tab.rb deleted file mode 100644 index 8595ee876a4947b988a9475b6f35a25660dd3fb2..0000000000000000000000000000000000000000 --- a/features/steps/profile/active_tab.rb +++ /dev/null @@ -1,25 +0,0 @@ -class Spinach::Features::ProfileActiveTab < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedActiveTab - - step 'the active main tab should be Home' do - ensure_active_main_tab('Profile') - end - - step 'the active main tab should be Account' do - ensure_active_main_tab('Account') - end - - step 'the active main tab should be SSH Keys' do - ensure_active_main_tab('SSH Keys') - end - - step 'the active main tab should be Design' do - ensure_active_main_tab('Design') - end - - step 'the active main tab should be History' do - ensure_active_main_tab('History') - end -end diff --git a/features/steps/profile/emails.rb b/features/steps/profile/emails.rb deleted file mode 100644 index 2b6ac37d8668162267358567e8416999b2489be4..0000000000000000000000000000000000000000 --- a/features/steps/profile/emails.rb +++ /dev/null @@ -1,48 +0,0 @@ -class Spinach::Features::ProfileEmails < Spinach::FeatureSteps - include SharedAuthentication - - step 'I visit profile emails page' do - visit profile_emails_path - end - - step 'I should see my emails' do - page.should have_content(@user.email) - @user.emails.each do |email| - page.should have_content(email.email) - end - end - - step 'I submit new email "my@email.com"' do - fill_in "email_email", with: "my@email.com" - click_button "Add" - end - - step 'I should see new email "my@email.com"' do - email = @user.emails.find_by(email: "my@email.com") - email.should_not be_nil - page.should have_content("my@email.com") - end - - step 'I should not see email "my@email.com"' do - email = @user.emails.find_by(email: "my@email.com") - email.should be_nil - page.should_not have_content("my@email.com") - end - - step 'I click link "Remove" for "my@email.com"' do - # there should only be one remove button at this time - click_link "Remove" - # force these to reload as they have been cached - @user.emails.reload - end - - step 'I submit duplicate email @user.email' do - fill_in "email_email", with: @user.email - click_button "Add" - end - - step 'I should not have @user.email added' do - email = @user.emails.find_by(email: @user.email) - email.should be_nil - end -end diff --git a/features/steps/profile/notifications.rb b/features/steps/profile/notifications.rb deleted file mode 100644 index 13e93618eb748d8f11c83cf1d8aa83f5991bba0d..0000000000000000000000000000000000000000 --- a/features/steps/profile/notifications.rb +++ /dev/null @@ -1,12 +0,0 @@ -class Spinach::Features::ProfileNotifications < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - - step 'I visit profile notifications page' do - visit profile_notifications_path - end - - step 'I should see global notifications settings' do - page.should have_content "Notifications Settings" - end -end diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb deleted file mode 100644 index 791982d16c3b433b87cac034ddc168d813965b94..0000000000000000000000000000000000000000 --- a/features/steps/profile/profile.rb +++ /dev/null @@ -1,242 +0,0 @@ -class Spinach::Features::Profile < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - - step 'I should see my profile info' do - page.should have_content "Profile Settings" - end - - step 'I change my profile info' do - fill_in "user_skype", with: "testskype" - fill_in "user_linkedin", with: "testlinkedin" - fill_in "user_twitter", with: "testtwitter" - fill_in "user_website_url", with: "testurl" - fill_in "user_location", with: "Ukraine" - click_button "Save changes" - @user.reload - end - - step 'I should see new profile info' do - @user.skype.should == 'testskype' - @user.linkedin.should == 'testlinkedin' - @user.twitter.should == 'testtwitter' - @user.website_url.should == 'testurl' - find("#user_location").value.should == "Ukraine" - end - - step 'I change my avatar' do - attach_file(:user_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png')) - click_button "Save changes" - @user.reload - end - - step 'I should see new avatar' do - @user.avatar.should be_instance_of AvatarUploader - @user.avatar.url.should == "/uploads/user/avatar/#{ @user.id }/gitlab_logo.png" - end - - step 'I should see the "Remove avatar" button' do - page.should have_link("Remove avatar") - end - - step 'I have an avatar' do - attach_file(:user_avatar, File.join(Rails.root, 'public', 'gitlab_logo.png')) - click_button "Save changes" - @user.reload - end - - step 'I remove my avatar' do - click_link "Remove avatar" - @user.reload - end - - step 'I should see my gravatar' do - @user.avatar?.should be_false - end - - step 'I should not see the "Remove avatar" button' do - page.should_not have_link("Remove avatar") - end - - step 'I try change my password w/o old one' do - within '.update-password' do - fill_in "user_password", with: "22233344" - fill_in "user_password_confirmation", with: "22233344" - click_button "Save" - end - end - - step 'I change my password' do - within '.update-password' do - fill_in "user_current_password", with: "12345678" - fill_in "user_password", with: "22233344" - fill_in "user_password_confirmation", with: "22233344" - click_button "Save" - end - end - - step 'I unsuccessfully change my password' do - within '.update-password' do - fill_in "user_current_password", with: "12345678" - fill_in "user_password", with: "password" - fill_in "user_password_confirmation", with: "confirmation" - click_button "Save" - end - end - - step "I should see a missing password error message" do - page.should have_content "You must provide a valid current password" - end - - step "I should see a password error message" do - page.should have_content "Password confirmation doesn't match" - end - - step 'I reset my token' do - within '.update-token' do - @old_token = @user.private_token - click_button "Reset" - end - end - - step 'I should see new token' do - find("#token").value.should_not == @old_token - find("#token").value.should == @user.reload.private_token - end - - step 'I have activity' do - create(:closed_issue_event, author: current_user) - end - - step 'I should see my activity' do - page.should have_content "#{current_user.name} closed issue" - end - - step "I change my application theme" do - within '.application-theme' do - choose "Violet" - end - end - - step "I change my code preview theme" do - within '.code-preview-theme' do - choose "Solarized dark" - end - end - - step "I should see the theme change immediately" do - page.should have_selector('body.ui_color') - page.should_not have_selector('body.ui_basic') - end - - step "I should receive feedback that the changes were saved" do - page.should have_content("saved") - end - - step 'my password is expired' do - current_user.update_attributes(password_expires_at: Time.now - 1.hour) - end - - step "I am not an ldap user" do - current_user.identities.delete - current_user.ldap_user?.should be_false - end - - step 'I redirected to expired password page' do - current_path.should == new_profile_password_path - end - - step 'I submit new password' do - fill_in :user_current_password, with: '12345678' - fill_in :user_password, with: '12345678' - fill_in :user_password_confirmation, with: '12345678' - click_button "Set new password" - end - - step 'I redirected to sign in page' do - current_path.should == new_user_session_path - end - - step 'I should be redirected to password page' do - current_path.should == edit_profile_password_path - end - - step 'I should be redirected to account page' do - current_path.should == profile_account_path - end - - step 'I click on my profile picture' do - click_link 'profile-pic' - end - - step 'I should see my user page' do - page.should have_content "User Activity" - - within '.navbar-gitlab' do - page.should have_content current_user.name - end - end - - step 'I have group with projects' do - @group = create(:group) - @group.add_owner(current_user) - @project = create(:project, namespace: @group) - @event = create(:closed_issue_event, project: @project) - - @project.team << [current_user, :master] - end - - step 'I should see groups I belong to' do - page.should have_css('.profile-groups-avatars', visible: true) - end - - step 'I click on new application button' do - click_on 'New Application' - end - - step 'I should see application form' do - page.should have_content "New application" - end - - step 'I fill application form out and submit' do - fill_in :doorkeeper_application_name, with: 'test' - fill_in :doorkeeper_application_redirect_uri, with: 'https://test.com' - click_on "Submit" - end - - step 'I see application' do - page.should have_content "Application: test" - page.should have_content "Application Id" - page.should have_content "Secret" - end - - step 'I click edit' do - click_on "Edit" - end - - step 'I see edit application form' do - page.should have_content "Edit application" - end - - step 'I change name of application and submit' do - page.should have_content "Edit application" - fill_in :doorkeeper_application_name, with: 'test_changed' - click_on "Submit" - end - - step 'I see that application was changed' do - page.should have_content "test_changed" - page.should have_content "Application Id" - page.should have_content "Secret" - end - - step 'I click to remove application' do - within '.oauth-applications' do - click_on "Destroy" - end - end - - step "I see that application is removed" do - page.find(".oauth-applications").should_not have_content "test_changed" - end -end diff --git a/features/steps/profile/ssh_keys.rb b/features/steps/profile/ssh_keys.rb deleted file mode 100644 index ea912e5b4da0c10f271db8ba8ca9593354d2da2f..0000000000000000000000000000000000000000 --- a/features/steps/profile/ssh_keys.rb +++ /dev/null @@ -1,46 +0,0 @@ -class Spinach::Features::ProfileSshKeys < Spinach::FeatureSteps - include SharedAuthentication - - step 'I should see my ssh keys' do - @user.keys.each do |key| - page.should have_content(key.title) - end - end - - step 'I click link "Add new"' do - click_link "Add SSH Key" - end - - step 'I submit new ssh key "Laptop"' do - fill_in "key_title", with: "Laptop" - fill_in "key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop" - click_button "Add key" - end - - step 'I should see new ssh key "Laptop"' do - key = Key.find_by(title: "Laptop") - page.should have_content(key.title) - page.should have_content(key.key) - current_path.should == profile_key_path(key) - end - - step 'I click link "Work"' do - click_link "Work" - end - - step 'I click link "Remove"' do - click_link "Remove" - end - - step 'I visit profile keys page' do - visit profile_keys_path - end - - step 'I should not see "Work" ssh key' do - page.should_not have_content "Work" - end - - step 'I have ssh key "ssh-rsa Work"' do - create(:key, user: @user, title: "ssh-rsa Work", key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+L3TbFegm3k8QjejSwemk4HhlRh+DuN679Pc5ckqE/MPhVtE/+kZQDYCTB284GiT2aIoGzmZ8ee9TkaoejAsBwlA+Wz2Q3vhz65X6sMgalRwpdJx8kSEUYV8ZPV3MZvPo8KdNg993o4jL6G36GDW4BPIyO6FPZhfsawdf6liVD0Xo5kibIK7B9VoE178cdLQtLpS2YolRwf5yy6XR6hbbBGQR+6xrGOdP16eGZDb1CE2bMvvJijjloFqPscGktWOqW+nfh5txwFfBzlfARDTBsS8WZtg3Yoj1kn33kPsWRlgHfNutFRAIynDuDdQzQq8tTtVwm+Yi75RfcPHW8y3P Work") - end -end diff --git a/features/steps/project/active_tab.rb b/features/steps/project/active_tab.rb deleted file mode 100644 index dd3215adb1a2a4ee84f67c7d7d322109f69214a9..0000000000000000000000000000000000000000 --- a/features/steps/project/active_tab.rb +++ /dev/null @@ -1,103 +0,0 @@ -class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - include SharedActiveTab - include SharedProjectTab - - # Sub Tabs: Home - - step 'I click the "Team" tab' do - click_link('Members') - end - - step 'I click the "Attachments" tab' do - click_link('Attachments') - end - - step 'I click the "Snippets" tab' do - click_link('Snippets') - end - - step 'I click the "Edit" tab' do - within '.project-settings-nav' do - click_link('Project') - end - end - - step 'I click the "Hooks" tab' do - click_link('Web Hooks') - end - - step 'I click the "Deploy Keys" tab' do - click_link('Deploy Keys') - end - - step 'the active sub nav should be Team' do - ensure_active_sub_nav('Members') - end - - step 'the active sub nav should be Edit' do - ensure_active_sub_nav('Project') - end - - step 'the active sub nav should be Hooks' do - ensure_active_sub_nav('Web Hooks') - end - - step 'the active sub nav should be Deploy Keys' do - ensure_active_sub_nav('Deploy Keys') - end - - # Sub Tabs: Commits - - step 'I click the "Compare" tab' do - click_link('Compare') - end - - step 'I click the "Branches" tab' do - click_link('Branches') - end - - step 'I click the "Tags" tab' do - click_link('Tags') - end - - step 'the active sub tab should be Commits' do - ensure_active_sub_tab('Commits') - end - - step 'the active sub tab should be Compare' do - ensure_active_sub_tab('Compare') - end - - step 'the active sub tab should be Branches' do - ensure_active_sub_tab('Branches') - end - - step 'the active sub tab should be Tags' do - ensure_active_sub_tab('Tags') - end - - # Sub Tabs: Issues - - step 'I click the "Milestones" tab' do - click_link('Milestones') - end - - step 'I click the "Labels" tab' do - click_link('Labels') - end - - step 'the active sub tab should be Issues' do - ensure_active_sub_tab('Issues') - end - - step 'the active main tab should be Milestones' do - ensure_active_main_tab('Milestones') - end - - step 'the active main tab should be Labels' do - ensure_active_main_tab('Labels') - end -end diff --git a/features/steps/project/archived.rb b/features/steps/project/archived.rb deleted file mode 100644 index 37ad0c776555da2384d9d501d2109f96daf5a8c6..0000000000000000000000000000000000000000 --- a/features/steps/project/archived.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Spinach::Features::ProjectArchived < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - When 'project "Forum" is archived' do - project = Project.find_by(name: "Forum") - project.update_attribute(:archived, true) - end - - When 'project "Shop" is archived' do - project = Project.find_by(name: "Shop") - project.update_attribute(:archived, true) - end - - When 'I visit project "Forum" page' do - project = Project.find_by(name: "Forum") - visit namespace_project_path(project.namespace, project) - end - - step 'I should not see "Archived"' do - page.should_not have_content "Archived" - end - - step 'I should see "Archived"' do - page.should have_content "Archived" - end - - When 'I set project archived' do - click_link "Archive" - end - - When 'I set project unarchived' do - click_link "Unarchive" - end - -end diff --git a/features/steps/project/commits/branches.rb b/features/steps/project/commits/branches.rb deleted file mode 100644 index 07f7e5796a3a04ad42e05b8da816e8b5bea0e594..0000000000000000000000000000000000000000 --- a/features/steps/project/commits/branches.rb +++ /dev/null @@ -1,85 +0,0 @@ -class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I click link "All"' do - click_link "All" - end - - step 'I should see "Shop" all branches list' do - page.should have_content "Branches" - page.should have_content "master" - end - - step 'I click link "Protected"' do - click_link "Protected" - end - - step 'I should see "Shop" protected branches list' do - within ".protected-branches-list" do - page.should have_content "stable" - page.should_not have_content "master" - end - end - - step 'project "Shop" has protected branches' do - project = Project.find_by(name: "Shop") - project.protected_branches.create(name: "stable") - end - - step 'I click new branch link' do - click_link "New branch" - end - - step 'I submit new branch form' do - fill_in 'branch_name', with: 'deploy_keys' - fill_in 'ref', with: 'master' - click_button 'Create branch' - end - - step 'I submit new branch form with invalid name' do - fill_in 'branch_name', with: '1.0 stable' - fill_in 'ref', with: 'master' - click_button 'Create branch' - end - - step 'I submit new branch form with invalid reference' do - fill_in 'branch_name', with: 'foo' - fill_in 'ref', with: 'foo' - click_button 'Create branch' - end - - step 'I submit new branch form with branch that already exists' do - fill_in 'branch_name', with: 'master' - fill_in 'ref', with: 'master' - click_button 'Create branch' - end - - step 'I should see new branch created' do - page.should have_content 'deploy_keys' - end - - step 'I should see new an error that branch is invalid' do - page.should have_content 'Branch name invalid' - end - - step 'I should see new an error that ref is invalid' do - page.should have_content 'Invalid reference name' - end - - step 'I should see new an error that branch already exists' do - page.should have_content 'Branch already exists' - end - - step "I click branch 'improve/awesome' delete link" do - within '.js-branch-improve\/awesome' do - find('.btn-remove').click - sleep 0.05 - end - end - - step "I should not see branch 'improve/awesome'" do - all(visible: true).should_not have_content 'improve/awesome' - end -end diff --git a/features/steps/project/commits/comments.rb b/features/steps/project/commits/comments.rb deleted file mode 100644 index 3d4d8ad636884f5b025b3f5f0a2f98a5b200b832..0000000000000000000000000000000000000000 --- a/features/steps/project/commits/comments.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Spinach::Features::ProjectCommitsComments < Spinach::FeatureSteps - include SharedAuthentication - include SharedNote - include SharedPaths - include SharedProject -end diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb deleted file mode 100644 index 57b727f837ed4d007f881f9c7dc551a16d3c7077..0000000000000000000000000000000000000000 --- a/features/steps/project/commits/commits.rb +++ /dev/null @@ -1,103 +0,0 @@ -class Spinach::Features::ProjectCommits < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include RepoHelpers - - step 'I see project commits' do - commit = @project.repository.commit - page.should have_content(@project.name) - page.should have_content(commit.message[0..20]) - page.should have_content(commit.short_id) - end - - step 'I click atom feed link' do - click_link "Feed" - end - - step 'I see commits atom feed' do - commit = @project.repository.commit - response_headers['Content-Type'].should have_content("application/atom+xml") - body.should have_selector("title", text: "Recent commits to #{@project.name}") - body.should have_selector("author email", text: commit.author_email) - body.should have_selector("entry summary", text: commit.description[0..10]) - end - - step 'I click on commit link' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.id) - end - - step 'I see commit info' do - page.should have_content sample_commit.message - page.should have_content "Showing #{sample_commit.files_changed_count} changed files" - end - - step 'I fill compare fields with refs' do - fill_in "from", with: sample_commit.parent_id - fill_in "to", with: sample_commit.id - click_button "Compare" - end - - step 'I unfold diff' do - @diff = first('.js-unfold') - @diff.click - sleep 2 - end - - step 'I should see additional file lines' do - within @diff.parent do - first('.new_line').text.should_not have_content "..." - end - end - - step 'I see compared refs' do - page.should have_content "Compare View" - page.should have_content "Commits (1)" - page.should have_content "Showing 2 changed files" - end - - step 'I see breadcrumb links' do - page.should have_selector('ul.breadcrumb') - page.should have_selector('ul.breadcrumb a', count: 4) - end - - step 'I see commits stats' do - page.should have_content 'Top 50 Committers' - page.should have_content 'Committers' - page.should have_content 'Total commits' - page.should have_content 'Authors' - end - - step 'I visit big commit page' do - Commit::DIFF_SAFE_FILES = 20 - visit namespace_project_commit_path(@project.namespace, @project, sample_big_commit.id) - end - - step 'I see big commit warning' do - page.should have_content sample_big_commit.message - page.should have_content "Too many changes" - Commit::DIFF_SAFE_FILES = 100 - end - - step 'I visit a commit with an image that changed' do - visit namespace_project_commit_path(@project.namespace, @project, sample_image_commit.id) - end - - step 'The diff links to both the previous and current image' do - links = all('.two-up span div a') - links[0]['href'].should =~ %r{blob/#{sample_image_commit.old_blob_id}} - links[1]['href'].should =~ %r{blob/#{sample_image_commit.new_blob_id}} - end - - step 'I click side-by-side diff button' do - click_link "Side-by-side" - end - - step 'I see side-by-side diff button' do - page.should have_content "Side-by-side" - end - - step 'I see inline diff button' do - page.should have_content "Inline" - end -end diff --git a/features/steps/project/commits/diff_comments.rb b/features/steps/project/commits/diff_comments.rb deleted file mode 100644 index b9d8cf2c5a55c8b60179f34875d251a3e3bc6b5b..0000000000000000000000000000000000000000 --- a/features/steps/project/commits/diff_comments.rb +++ /dev/null @@ -1,6 +0,0 @@ -class Spinach::Features::ProjectCommitsDiffComments < Spinach::FeatureSteps - include SharedAuthentication - include SharedDiffNote - include SharedPaths - include SharedProject -end diff --git a/features/steps/project/commits/tags.rb b/features/steps/project/commits/tags.rb deleted file mode 100644 index 3465fcbfd072dfc8c37afc7b3711a11bcf6eeff9..0000000000000000000000000000000000000000 --- a/features/steps/project/commits/tags.rb +++ /dev/null @@ -1,82 +0,0 @@ -class Spinach::Features::ProjectCommitsTags < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I should see "Shop" all tags list' do - page.should have_content "Tags" - page.should have_content "v1.0.0" - end - - step 'I click new tag link' do - click_link 'New tag' - end - - step 'I submit new tag form' do - fill_in 'tag_name', with: 'v7.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I submit new tag form with invalid name' do - fill_in 'tag_name', with: 'v 1.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I submit new tag form with invalid reference' do - fill_in 'tag_name', with: 'foo' - fill_in 'ref', with: 'foo' - click_button 'Create tag' - end - - step 'I submit new tag form with tag that already exists' do - fill_in 'tag_name', with: 'v1.0.0' - fill_in 'ref', with: 'master' - click_button 'Create tag' - end - - step 'I should see new tag created' do - page.should have_content 'v7.0' - end - - step 'I should see new an error that tag is invalid' do - page.should have_content 'Tag name invalid' - end - - step 'I should see new an error that tag ref is invalid' do - page.should have_content 'Invalid reference name' - end - - step 'I should see new an error that tag already exists' do - page.should have_content 'Tag already exists' - end - - step "I delete tag 'v1.1.0'" do - within '.tags' do - first('.btn-remove').click - sleep 0.05 - end - end - - step "I should not see tag 'v1.1.0'" do - within '.tags' do - all(visible: true).should_not have_content 'v1.1.0' - end - end - - step 'I delete all tags' do - within '.tags' do - all('.btn-remove').each do |remove| - remove.click - sleep 0.05 - end - end - end - - step 'I should see tags info message' do - within '.tags' do - page.should have_content 'Repository has no tags yet.' - end - end -end diff --git a/features/steps/project/commits/user_lookup.rb b/features/steps/project/commits/user_lookup.rb deleted file mode 100644 index 63ff84c82ef0645a0d08fbc53bc8b506f54106c5..0000000000000000000000000000000000000000 --- a/features/steps/project/commits/user_lookup.rb +++ /dev/null @@ -1,48 +0,0 @@ -class Spinach::Features::ProjectCommitsUserLookup < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I click on commit link' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.id) - end - - step 'I click on another commit link' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.parent_id) - end - - step 'I have user with primary email' do - user_primary - end - - step 'I have user with secondary email' do - user_secondary - end - - step 'I see author based on primary email' do - check_author_link(sample_commit.author_email, user_primary) - end - - step 'I see author based on secondary email' do - check_author_link(sample_commit.author_email, user_secondary) - end - - def check_author_link(email, user) - author_link = find('.commit-author-link') - author_link['href'].should == user_path(user) - author_link['data-original-title'].should == email - find('.commit-author-name').text.should == user.name - end - - def user_primary - @user_primary ||= create(:user, email: 'dmitriy.zaporozhets@gmail.com') - end - - def user_secondary - @user_secondary ||= begin - user = create(:user, email: 'dzaporozhets@example.com') - create(:email, { user: user, email: 'dmitriy.zaporozhets@gmail.com' }) - user - end - end -end diff --git a/features/steps/project/create.rb b/features/steps/project/create.rb deleted file mode 100644 index 6b85cf74f5f239b718ff0085cf7ea252ad71c32f..0000000000000000000000000000000000000000 --- a/features/steps/project/create.rb +++ /dev/null @@ -1,42 +0,0 @@ -class Spinach::Features::ProjectCreate < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - - step 'fill project form with valid data' do - fill_in 'project_path', with: 'Empty' - click_button "Create project" - end - - step 'I should see project page' do - page.should have_content "Empty" - current_path.should == namespace_project_path(Project.last.namespace, Project.last) - end - - step 'I should see empty project instuctions' do - page.should have_content "git init" - page.should have_content "git remote" - page.should have_content Project.last.url_to_repo - end - - step 'I see empty project instuctions' do - page.should have_content "git init" - page.should have_content "git remote" - page.should have_content Project.last.url_to_repo - end - - step 'I click on HTTP' do - click_button 'HTTP' - end - - step 'Remote url should update to http link' do - page.should have_content "git remote add origin #{Project.last.http_url_to_repo}" - end - - step 'If I click on SSH' do - click_button 'SSH' - end - - step 'Remote url should update to ssh link' do - page.should have_content "git remote add origin #{Project.last.url_to_repo}" - end -end diff --git a/features/steps/project/deploy_keys.rb b/features/steps/project/deploy_keys.rb deleted file mode 100644 index 50e14513a7a28a294c575976e60d12d48bc67025..0000000000000000000000000000000000000000 --- a/features/steps/project/deploy_keys.rb +++ /dev/null @@ -1,77 +0,0 @@ -class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'project has deploy key' do - create(:deploy_keys_project, project: @project) - end - - step 'I should see project deploy key' do - within '.enabled-keys' do - page.should have_content deploy_key.title - end - end - - step 'I should see other project deploy key' do - within '.available-keys' do - page.should have_content other_deploy_key.title - end - end - - step 'I should see public deploy key' do - within '.available-keys' do - page.should have_content public_deploy_key.title - end - end - - step 'I click \'New Deploy Key\'' do - click_link 'New Deploy Key' - end - - step 'I submit new deploy key' do - fill_in "deploy_key_title", with: "laptop" - fill_in "deploy_key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop" - click_button "Create" - end - - step 'I should be on deploy keys page' do - current_path.should == namespace_project_deploy_keys_path(@project.namespace, @project) - end - - step 'I should see newly created deploy key' do - within '.enabled-keys' do - page.should have_content(deploy_key.title) - end - end - - step 'other project has deploy key' do - @second_project = create :project, namespace: create(:group) - @second_project.team << [current_user, :master] - create(:deploy_keys_project, project: @second_project) - end - - step 'public deploy key exists' do - create(:deploy_key, public: true) - end - - step 'I click attach deploy key' do - within '.available-keys' do - click_link 'Enable' - end - end - - protected - - def deploy_key - @project.deploy_keys.last - end - - def other_deploy_key - @second_project.deploy_keys.last - end - - def public_deploy_key - DeployKey.are_public.last - end -end diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb deleted file mode 100644 index 8e58597db205f47ea0b4ad4076903cfc1817c005..0000000000000000000000000000000000000000 --- a/features/steps/project/fork.rb +++ /dev/null @@ -1,34 +0,0 @@ -class Spinach::Features::ProjectFork < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I click link "Fork"' do - page.should have_content "Shop" - page.should have_content "Fork" - click_link "Fork" - end - - step 'I am a member of project "Shop"' do - @project = create(:project, name: "Shop") - @project.team << [@user, :reporter] - end - - step 'I should see the forked project page' do - page.should have_content "Project was successfully forked." - end - - step 'I already have a project named "Shop" in my namespace' do - @my_project = create(:project, name: "Shop", namespace: current_user.namespace) - end - - step 'I should see a "Name has already been taken" warning' do - page.should have_content "Name has already been taken" - end - - step 'I fork to my namespace' do - within '.fork-namespaces' do - click_link current_user.name - end - end -end diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb deleted file mode 100644 index 63ad90e124135bc42b81fd4ce52109b5b43fe7f4..0000000000000000000000000000000000000000 --- a/features/steps/project/forked_merge_requests.rb +++ /dev/null @@ -1,136 +0,0 @@ -class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - include Select2Helper - - step 'I am a member of project "Shop"' do - @project = Project.find_by(name: "Shop") - @project ||= create(:project, name: "Shop") - @project.team << [@user, :reporter] - @project.ensure_satellite_exists - end - - step 'I have a project forked off of "Shop" called "Forked Shop"' do - @forked_project = Projects::ForkService.new(@project, @user).execute - end - - step 'I click link "New Merge Request"' do - click_link "New Merge Request" - end - - step 'I should see merge request "Merge Request On Forked Project"' do - @project.merge_requests.size.should >= 1 - @merge_request = @project.merge_requests.last - current_path.should == namespace_project_merge_request_path(@project.namespace, @project, @merge_request) - @merge_request.title.should == "Merge Request On Forked Project" - @merge_request.source_project.should == @forked_project - @merge_request.source_branch.should == "fix" - @merge_request.target_branch.should == "master" - page.should have_content @forked_project.path_with_namespace - page.should have_content @project.path_with_namespace - page.should have_content @merge_request.source_branch - page.should have_content @merge_request.target_branch - end - - step 'I fill out a "Merge Request On Forked Project" merge request' do - select @forked_project.path_with_namespace, from: "merge_request_source_project_id" - select @project.path_with_namespace, from: "merge_request_target_project_id" - select "fix", from: "merge_request_source_branch" - select "master", from: "merge_request_target_branch" - - click_button "Compare branches" - - fill_in "merge_request_title", with: "Merge Request On Forked Project" - end - - step 'I submit the merge request' do - click_button "Submit merge request" - end - - step 'I follow the target commit link' do - commit = @project.repository.commit - click_link commit.short_id(8) - end - - step 'I should see the commit under the forked from project' do - commit = @project.repository.commit - page.should have_content(commit.message) - end - - step 'I click "Create Merge Request on fork" link' do - click_link "Create Merge Request on fork" - end - - step 'I see prefilled new Merge Request page for the forked project' do - current_path.should == new_namespace_project_merge_request_path(@forked_project.namespace, @forked_project) - find("#merge_request_source_project_id").value.should == @forked_project.id.to_s - find("#merge_request_target_project_id").value.should == @project.id.to_s - find("#merge_request_source_branch").value.should have_content "new_design" - find("#merge_request_target_branch").value.should have_content "master" - find("#merge_request_title").value.should == "New Design" - verify_commit_link(".mr_target_commit", @project) - verify_commit_link(".mr_source_commit", @forked_project) - end - - step 'I update the merge request title' do - fill_in "merge_request_title", with: "An Edited Forked Merge Request" - end - - step 'I save the merge request' do - click_button "Save changes" - end - - step 'I should see the edited merge request' do - page.should have_content "An Edited Forked Merge Request" - @project.merge_requests.size.should >= 1 - @merge_request = @project.merge_requests.last - current_path.should == namespace_project_merge_request_path(@project.namespace, @project, @merge_request) - @merge_request.source_project.should == @forked_project - @merge_request.source_branch.should == "fix" - @merge_request.target_branch.should == "master" - page.should have_content @forked_project.path_with_namespace - page.should have_content @project.path_with_namespace - page.should have_content @merge_request.source_branch - page.should have_content @merge_request.target_branch - end - - step 'I should see last push widget' do - page.should have_content "You pushed to new_design" - page.should have_link "Create Merge Request" - end - - step 'I click link edit "Merge Request On Forked Project"' do - find("#edit_merge_request").click - end - - step 'I see the edit page prefilled for "Merge Request On Forked Project"' do - current_path.should == edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) - page.should have_content "Edit merge request ##{@merge_request.id}" - find("#merge_request_title").value.should == "Merge Request On Forked Project" - end - - step 'I fill out an invalid "Merge Request On Forked Project" merge request' do - select "Select branch", from: "merge_request_target_branch" - find(:select, "merge_request_source_project_id", {}).value.should == @forked_project.id.to_s - find(:select, "merge_request_target_project_id", {}).value.should == @project.id.to_s - find(:select, "merge_request_source_branch", {}).value.should == "" - find(:select, "merge_request_target_branch", {}).value.should == "" - click_button "Compare branches" - end - - step 'I should see validation errors' do - page.should have_content "You must select source and target branch" - end - - step 'the target repository should be the original repository' do - page.should have_select("merge_request_target_project_id", selected: @project.path_with_namespace) - end - - # Verify a link is generated against the correct project - def verify_commit_link(container_div, container_project) - # This should force a wait for the javascript to execute - find(:div,container_div).find(".commit_short_id")['href'].should have_content "#{container_project.path_with_namespace}/commit" - end -end diff --git a/features/steps/project/graph.rb b/features/steps/project/graph.rb deleted file mode 100644 index a2807c340f6824156c17315bf270f9b377cd26d2..0000000000000000000000000000000000000000 --- a/features/steps/project/graph.rb +++ /dev/null @@ -1,23 +0,0 @@ -class Spinach::Features::ProjectGraph < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - - step 'page should have graphs' do - page.should have_selector ".stat-graph" - end - - When 'I visit project "Shop" graph page' do - project = Project.find_by(name: "Shop") - visit namespace_project_graph_path(project.namespace, project, "master") - end - - step 'I visit project "Shop" commits graph page' do - project = Project.find_by(name: "Shop") - visit commits_namespace_project_graph_path(project.namespace, project, "master") - end - - step 'page should have commits graphs' do - page.should have_content "Commit statistics for master" - page.should have_content "Commits per day of month" - end -end diff --git a/features/steps/project/hooks.rb b/features/steps/project/hooks.rb deleted file mode 100644 index 4b1352025934e64da3bfb20ea3d28246b29d3206..0000000000000000000000000000000000000000 --- a/features/steps/project/hooks.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'webmock' - -class Spinach::Features::ProjectHooks < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include RSpec::Matchers - include RSpec::Mocks::ExampleMethods - include WebMock::API - - step 'project has hook' do - @hook = create(:project_hook, project: current_project) - end - - step 'I own empty project with hook' do - @project = create(:empty_project, - name: 'Empty Project', namespace: @user.namespace) - @hook = create(:project_hook, project: current_project) - end - - step 'I should see project hook' do - page.should have_content @hook.url - end - - step 'I submit new hook' do - @url = Faker::Internet.uri("http") - fill_in "hook_url", with: @url - expect { click_button "Add Web Hook" }.to change(ProjectHook, :count).by(1) - end - - step 'I should see newly created hook' do - current_path.should == namespace_project_hooks_path(current_project.namespace, current_project) - page.should have_content(@url) - end - - step 'I click test hook button' do - stub_request(:post, @hook.url).to_return(status: 200) - click_link 'Test Hook' - end - - step 'I click test hook button with invalid URL' do - stub_request(:post, @hook.url).to_raise(SocketError) - click_link 'Test Hook' - end - - step 'hook should be triggered' do - current_path.should == namespace_project_hooks_path(current_project.namespace, current_project) - page.should have_selector '.flash-notice', - text: 'Hook successfully executed.' - end - - step 'I should see hook error message' do - page.should have_selector '.flash-alert', - text: 'Hook execution failed. '\ - 'Ensure the project has commits.' - end - - step 'I should see hook service down error message' do - page.should have_selector '.flash-alert', - text: 'Hook execution failed. '\ - 'Ensure hook URL is correct and '\ - 'service is up.' - end -end diff --git a/features/steps/project/issues/filter_labels.rb b/features/steps/project/issues/filter_labels.rb deleted file mode 100644 index 5740bd12837ba6aa0e1a5f172270c9beecc42d07..0000000000000000000000000000000000000000 --- a/features/steps/project/issues/filter_labels.rb +++ /dev/null @@ -1,60 +0,0 @@ -class Spinach::Features::ProjectIssuesFilterLabels < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include Select2Helper - - step 'I should see "Bugfix1" in issues list' do - within ".issues-list" do - page.should have_content "Bugfix1" - end - end - - step 'I should see "Bugfix2" in issues list' do - within ".issues-list" do - page.should have_content "Bugfix2" - end - end - - step 'I should not see "Bugfix2" in issues list' do - within ".issues-list" do - page.should_not have_content "Bugfix2" - end - end - - step 'I should not see "Feature1" in issues list' do - within ".issues-list" do - page.should_not have_content "Feature1" - end - end - - step 'I click link "bug"' do - select2('bug', from: "#label_name") - end - - step 'I click link "feature"' do - within ".labels-filter" do - click_link "feature" - end - end - - step 'project "Shop" has issue "Bugfix1" with labels: "bug", "feature"' do - project = Project.find_by(name: "Shop") - issue = create(:issue, title: "Bugfix1", project: project) - issue.labels << project.labels.find_by(title: 'bug') - issue.labels << project.labels.find_by(title: 'feature') - end - - step 'project "Shop" has issue "Bugfix2" with labels: "bug", "enhancement"' do - project = Project.find_by(name: "Shop") - issue = create(:issue, title: "Bugfix2", project: project) - issue.labels << project.labels.find_by(title: 'bug') - issue.labels << project.labels.find_by(title: 'enhancement') - end - - step 'project "Shop" has issue "Feature1" with labels: "feature"' do - project = Project.find_by(name: "Shop") - issue = create(:issue, title: "Feature1", project: project) - issue.labels << project.labels.find_by(title: 'feature') - end -end diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb deleted file mode 100644 index b8e282b2029d51b7790bc79045fd7b4d0e36df73..0000000000000000000000000000000000000000 --- a/features/steps/project/issues/issues.rb +++ /dev/null @@ -1,276 +0,0 @@ -class Spinach::Features::ProjectIssues < Spinach::FeatureSteps - include SharedAuthentication - include SharedIssuable - include SharedProject - include SharedNote - include SharedPaths - include SharedMarkdown - - step 'I should see "Release 0.4" in issues' do - page.should have_content "Release 0.4" - end - - step 'I should not see "Release 0.3" in issues' do - page.should_not have_content "Release 0.3" - end - - step 'I should not see "Tweet control" in issues' do - page.should_not have_content "Tweet control" - end - - step 'I should see that I am subscribed' do - find(".subscribe-button span").text.should == "Unsubscribe" - end - - step 'I should see that I am unsubscribed' do - sleep 0.2 - find(".subscribe-button span").text.should == "Subscribe" - end - - step 'I click link "Closed"' do - click_link "Closed" - end - - step 'I click button "Unsubscribe"' do - click_on "Unsubscribe" - end - - step 'I should see "Release 0.3" in issues' do - page.should have_content "Release 0.3" - end - - step 'I should not see "Release 0.4" in issues' do - page.should_not have_content "Release 0.4" - end - - step 'I click link "All"' do - click_link "All" - end - - step 'I click link "Release 0.4"' do - click_link "Release 0.4" - end - - step 'I should see issue "Release 0.4"' do - page.should have_content "Release 0.4" - end - - step 'I click link "New Issue"' do - click_link "New Issue" - end - - step 'I click "author" dropdown' do - first('.ajax-users-select').click - end - - step 'I see current user as the first user' do - expect(page).to have_selector('.user-result', visible: true, count: 4) - users = page.all('.user-name') - users[0].text.should == 'Any' - users[1].text.should == 'Unassigned' - users[2].text.should == current_user.name - end - - step 'I submit new issue "500 error on profile"' do - fill_in "issue_title", with: "500 error on profile" - click_button "Submit new issue" - end - - step 'I submit new issue "500 error on profile" with label \'bug\'' do - fill_in "issue_title", with: "500 error on profile" - select 'bug', from: "Labels" - click_button "Submit new issue" - end - - step 'I click link "500 error on profile"' do - click_link "500 error on profile" - end - - step 'I should see label \'bug\' with issue' do - within '.issue-show-labels' do - page.should have_content 'bug' - end - end - - step 'I should see issue "500 error on profile"' do - issue = Issue.find_by(title: "500 error on profile") - page.should have_content issue.title - page.should have_content issue.author_name - page.should have_content issue.project.name - end - - step 'I fill in issue search with "Re"' do - filter_issue "Re" - end - - step 'I fill in issue search with "Bu"' do - filter_issue "Bu" - end - - step 'I fill in issue search with ".3"' do - filter_issue ".3" - end - - step 'I fill in issue search with "Something"' do - filter_issue "Something" - end - - step 'I fill in issue search with ""' do - filter_issue "" - end - - step 'project "Shop" has milestone "v2.2"' do - - milestone = create(:milestone, title: "v2.2", project: project) - - 3.times { create(:issue, project: project, milestone: milestone) } - end - - step 'project "Shop" has milestone "v3.0"' do - - milestone = create(:milestone, title: "v3.0", project: project) - - 3.times { create(:issue, project: project, milestone: milestone) } - end - - When 'I select milestone "v3.0"' do - select "v3.0", from: "milestone_id" - end - - step 'I should see selected milestone with title "v3.0"' do - issues_milestone_selector = "#issue_milestone_id_chzn > a" - find(issues_milestone_selector).should have_content("v3.0") - end - - When 'I select first assignee from "Shop" project' do - - first_assignee = project.users.first - select first_assignee.name, from: "assignee_id" - end - - step 'I should see first assignee from "Shop" as selected assignee' do - issues_assignee_selector = "#issue_assignee_id_chzn > a" - - assignee_name = project.users.first.name - find(issues_assignee_selector).should have_content(assignee_name) - end - - step 'project "Shop" have "Release 0.4" open issue' do - - create(:issue, - title: "Release 0.4", - project: project, - author: project.users.first, - description: "# Description header" - ) - end - - step 'project "Shop" have "Tweet control" open issue' do - create(:issue, - title: "Tweet control", - project: project, - author: project.users.first) - end - - step 'project "Shop" have "Release 0.3" closed issue' do - create(:closed_issue, - title: "Release 0.3", - project: project, - author: project.users.first) - end - - step 'project "Shop" has "Tasks-open" open issue with task markdown' do - create_taskable(:issue, 'Tasks-open') - end - - step 'project "Shop" has "Tasks-closed" closed issue with task markdown' do - create_taskable(:closed_issue, 'Tasks-closed') - end - - step 'empty project "Empty Project"' do - create :empty_project, name: 'Empty Project', namespace: @user.namespace - end - - When 'I visit empty project page' do - project = Project.find_by(name: 'Empty Project') - visit namespace_project_path(project.namespace, project) - end - - step 'I see empty project details with ssh clone info' do - project = Project.find_by(name: 'Empty Project') - all(:css, '.git-empty .clone').each do |element| - element.text.should include(project.url_to_repo) - end - end - - When "I visit empty project's issues page" do - project = Project.find_by(name: 'Empty Project') - visit namespace_project_issues_path(project.namespace, project) - end - - step 'I leave a comment with code block' do - within(".js-main-target-form") do - fill_in "note[note]", with: "```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```" - click_button "Add Comment" - sleep 0.05 - end - end - - step 'I should see an error alert section within the comment form' do - within(".js-main-target-form") do - find(".error-alert") - end - end - - step 'The code block should be unchanged' do - page.should have_content("```\nCommand [1]: /usr/local/bin/git , see [text](doc/text)\n```") - end - - step 'project \'Shop\' has issue \'Bugfix1\' with description: \'Description for issue1\'' do - issue = create(:issue, title: 'Bugfix1', description: 'Description for issue1', project: project) - end - - step 'project \'Shop\' has issue \'Feature1\' with description: \'Feature submitted for issue1\'' do - issue = create(:issue, title: 'Feature1', description: 'Feature submitted for issue1', project: project) - end - - step 'I fill in issue search with \'Description for issue1\'' do - filter_issue 'Description for issue' - end - - step 'I fill in issue search with \'issue1\'' do - filter_issue 'issue1' - end - - step 'I fill in issue search with \'Rock and roll\'' do - filter_issue 'Description for issue' - end - - step 'I should see \'Bugfix1\' in issues' do - page.should have_content 'Bugfix1' - end - - step 'I should see \'Feature1\' in issues' do - page.should have_content 'Feature1' - end - - step 'I should not see \'Bugfix1\' in issues' do - page.should_not have_content 'Bugfix1' - end - - step 'issue \'Release 0.4\' has label \'bug\'' do - label = project.labels.create!(name: 'bug', color: '#990000') - issue = Issue.find_by!(title: 'Release 0.4') - issue.labels << label - end - - step 'I click label \'bug\'' do - within ".issues-list" do - click_link 'bug' - end - end - - def filter_issue(text) - fill_in 'issue_search', with: text - end -end diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb deleted file mode 100644 index 6ce34c500c6f5d1ffc494a711f0dc9fb2d929976..0000000000000000000000000000000000000000 --- a/features/steps/project/issues/labels.rb +++ /dev/null @@ -1,101 +0,0 @@ -class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I visit \'bug\' label edit page' do - visit edit_namespace_project_label_path(project.namespace, project, bug_label) - end - - step 'I remove label \'bug\'' do - within "#label_#{bug_label.id}" do - click_link 'Remove' - end - end - - step 'I delete all labels' do - within '.labels' do - all('.btn-remove').each do |remove| - remove.click - sleep 0.05 - end - end - end - - step 'I should see labels help message' do - within '.labels' do - page.should have_content 'Create first label or generate default set of '\ - 'labels' - end - end - - step 'I submit new label \'support\'' do - fill_in 'Title', with: 'support' - fill_in 'Background Color', with: '#F95610' - click_button 'Save' - end - - step 'I submit new label \'bug\'' do - fill_in 'Title', with: 'bug' - fill_in 'Background Color', with: '#F95610' - click_button 'Save' - end - - step 'I submit new label with invalid color' do - fill_in 'Title', with: 'support' - fill_in 'Background Color', with: '#12' - click_button 'Save' - end - - step 'I should see label label exist error message' do - within '.label-form' do - page.should have_content 'Title has already been taken' - end - end - - step 'I should see label color error message' do - within '.label-form' do - page.should have_content 'Color is invalid' - end - end - - step 'I should see label \'feature\'' do - within '.manage-labels-list' do - page.should have_content 'feature' - end - end - - step 'I should see label \'bug\'' do - within '.manage-labels-list' do - page.should have_content 'bug' - end - end - - step 'I should not see label \'bug\'' do - within '.manage-labels-list' do - page.should_not have_content 'bug' - end - end - - step 'I should see label \'support\'' do - within '.manage-labels-list' do - page.should have_content 'support' - end - end - - step 'I change label \'bug\' to \'fix\'' do - fill_in 'Title', with: 'fix' - fill_in 'Background Color', with: '#F15610' - click_button 'Save' - end - - step 'I should see label \'fix\'' do - within '.manage-labels-list' do - page.should have_content 'fix' - end - end - - def bug_label - project.labels.find_or_create_by(title: 'bug') - end -end diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb deleted file mode 100644 index cce87a6d9817a192da022c3f36f6afd0d1ac5129..0000000000000000000000000000000000000000 --- a/features/steps/project/issues/milestones.rb +++ /dev/null @@ -1,59 +0,0 @@ -class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include SharedMarkdown - - step 'I should see milestone "v2.2"' do - milestone = @project.milestones.find_by(title: "v2.2") - page.should have_content(milestone.title[0..10]) - page.should have_content(milestone.expires_at) - page.should have_content("Issues") - end - - step 'I click link "v2.2"' do - click_link "v2.2" - end - - step 'I click link "New Milestone"' do - click_link "New Milestone" - end - - step 'I submit new milestone "v2.3"' do - fill_in "milestone_title", with: "v2.3" - click_button "Create milestone" - end - - step 'I should see milestone "v2.3"' do - milestone = @project.milestones.find_by(title: "v2.3") - page.should have_content(milestone.title[0..10]) - page.should have_content(milestone.expires_at) - page.should have_content("Issues") - end - - step 'project "Shop" has milestone "v2.2"' do - project = Project.find_by(name: "Shop") - milestone = create(:milestone, - title: "v2.2", - project: project, - description: "# Description header" - ) - 3.times { create(:issue, project: project, milestone: milestone) } - end - - step 'the milestone has open and closed issues' do - project = Project.find_by(name: "Shop") - milestone = project.milestones.find_by(title: 'v2.2') - - # 3 Open issues created above; create one closed issue - create(:closed_issue, project: project, milestone: milestone) - end - - When 'I click link "All Issues"' do - click_link 'All Issues' - end - - step 'I should see 3 issues' do - page.should have_selector('#tab-issues li.issue-row', count: 4) - end -end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb deleted file mode 100644 index bb1f9f129c0cbb28ba43c92ff0bfd56cde8393cc..0000000000000000000000000000000000000000 --- a/features/steps/project/merge_requests.rb +++ /dev/null @@ -1,337 +0,0 @@ -class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps - include SharedAuthentication - include SharedIssuable - include SharedProject - include SharedNote - include SharedPaths - include SharedMarkdown - include SharedDiffNote - - step 'I click link "New Merge Request"' do - click_link "New Merge Request" - end - - step 'I click link "Bug NS-04"' do - click_link "Bug NS-04" - end - - step 'I click link "All"' do - click_link "All" - end - - step 'I click link "Closed"' do - click_link "Closed" - end - - step 'I should see merge request "Wiki Feature"' do - within '.merge-request' do - page.should have_content "Wiki Feature" - end - end - - step 'I should see closed merge request "Bug NS-04"' do - merge_request = MergeRequest.find_by!(title: "Bug NS-04") - merge_request.closed?.should be_true - page.should have_content "Closed by" - end - - step 'I should see merge request "Bug NS-04"' do - page.should have_content "Bug NS-04" - end - - step 'I should see "Bug NS-04" in merge requests' do - page.should have_content "Bug NS-04" - end - - step 'I should see "Feature NS-03" in merge requests' do - page.should have_content "Feature NS-03" - end - - step 'I should not see "Feature NS-03" in merge requests' do - page.should_not have_content "Feature NS-03" - end - - - step 'I should not see "Bug NS-04" in merge requests' do - page.should_not have_content "Bug NS-04" - end - - step 'I should see that I am subscribed' do - find(".subscribe-button span").text.should == "Unsubscribe" - end - - step 'I should see that I am unsubscribed' do - find(".subscribe-button span").should have_content("Subscribe") - end - - step 'I click button "Unsubscribe"' do - click_on "Unsubscribe" - end - - step 'I click link "Close"' do - first(:css, '.close-mr-link').click - end - - step 'I submit new merge request "Wiki Feature"' do - select "fix", from: "merge_request_source_branch" - select "feature", from: "merge_request_target_branch" - click_button "Compare branches" - fill_in "merge_request_title", with: "Wiki Feature" - click_button "Submit merge request" - end - - step 'project "Shop" have "Bug NS-04" open merge request' do - create(:merge_request, - title: "Bug NS-04", - source_project: project, - target_project: project, - source_branch: 'fix', - target_branch: 'master', - author: project.users.first, - description: "# Description header" - ) - end - - step 'project "Shop" have "Bug NS-05" open merge request with diffs inside' do - create(:merge_request_with_diffs, - title: "Bug NS-05", - source_project: project, - target_project: project, - author: project.users.first) - end - - step 'project "Shop" have "Feature NS-03" closed merge request' do - create(:closed_merge_request, - title: "Feature NS-03", - source_project: project, - target_project: project, - author: project.users.first) - end - - step 'project "Shop" has "MR-task-open" open MR with task markdown' do - create_taskable(:merge_request, 'MR-task-open') - end - - step 'I switch to the diff tab' do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) - end - - step 'I click on the Changes tab via Javascript' do - find('.diffs-tab').click - sleep 2 - end - - step 'I should see the proper Inline and Side-by-side links' do - buttons = all('#commit-diff-viewtype') - expect(buttons.count).to eq(2) - - buttons.each do |b| - expect(b['href']).should_not have_content('json') - end - end - - step 'I switch to the merge request\'s comments tab' do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) - end - - step 'I click on the commit in the merge request' do - within '.merge-request-tabs' do - click_link 'Commits' - end - - within '.commits' do - click_link Commit.truncate_sha(sample_commit.id) - end - end - - step 'I leave a comment on the diff page' do - init_diff_note - leave_comment "One comment to rule them all" - end - - step 'I leave a comment on the diff page in commit' do - click_diff_line(sample_commit.line_code) - leave_comment "One comment to rule them all" - end - - step 'I leave a comment like "Line is wrong" on diff' do - init_diff_note - leave_comment "Line is wrong" - end - - step 'I leave a comment like "Line is wrong" on diff in commit' do - click_diff_line(sample_commit.line_code) - leave_comment "Line is wrong" - end - - step 'I should see a discussion has started on diff' do - page.should have_content "#{current_user.name} started a discussion" - page.should have_content sample_commit.line_code_path - page.should have_content "Line is wrong" - end - - step 'I should see a discussion has started on commit diff' do - page.should have_content "#{current_user.name} started a discussion on commit" - page.should have_content sample_commit.line_code_path - page.should have_content "Line is wrong" - end - - step 'I should see a discussion has started on commit' do - page.should have_content "#{current_user.name} started a discussion on commit" - page.should have_content "One comment to rule them all" - end - - step 'merge request is mergeable' do - page.should have_button 'Accept Merge Request' - end - - step 'I modify merge commit message' do - find('.modify-merge-commit-link').click - fill_in 'commit_message', with: 'wow such merge' - end - - step 'merge request "Bug NS-05" is mergeable' do - merge_request.mark_as_mergeable - end - - step 'I accept this merge request' do - Gitlab::Satellite::MergeAction.any_instance.stub( - merge!: true, - ) - - within '.can_be_merged' do - click_button "Accept Merge Request" - end - end - - step 'I should see merged request' do - within '.issue-box' do - page.should have_content "Merged" - end - end - - step 'I click link "Reopen"' do - first(:css, '.reopen-mr-link').click - end - - step 'I should see reopened merge request "Bug NS-04"' do - within '.issue-box' do - page.should have_content "Open" - end - end - - step 'I click link "Hide inline discussion" of the second file' do - within '.files [id^=diff]:nth-child(2)' do - find('.js-toggle-diff-comments').click - end - end - - step 'I click link "Show inline discussion" of the second file' do - within '.files [id^=diff]:nth-child(2)' do - find('.js-toggle-diff-comments').click - end - end - - step 'I should not see a comment like "Line is wrong" in the second file' do - within '.files [id^=diff]:nth-child(2)' do - page.should_not have_visible_content "Line is wrong" - end - end - - step 'I should see a comment like "Line is wrong" in the second file' do - within '.files [id^=diff]:nth-child(2) .note-body > .note-text' do - page.should have_visible_content "Line is wrong" - end - end - - step 'I should not see a comment like "Line is wrong here" in the second file' do - within '.files [id^=diff]:nth-child(2)' do - page.should_not have_visible_content "Line is wrong here" - end - end - - step 'I should see a comment like "Line is wrong here" in the second file' do - within '.files [id^=diff]:nth-child(2) .note-body > .note-text' do - page.should have_visible_content "Line is wrong here" - end - end - - step 'I leave a comment like "Line is correct" on line 12 of the first file' do - init_diff_note_first_file - - within(".js-discussion-note-form") do - fill_in "note_note", with: "Line is correct" - click_button "Add Comment" - end - - within ".files [id^=diff]:nth-child(1) .note-body > .note-text" do - page.should have_content "Line is correct" - end - end - - step 'I leave a comment like "Line is wrong" on line 39 of the second file' do - init_diff_note_second_file - - within(".js-discussion-note-form") do - fill_in "note_note", with: "Line is wrong on here" - click_button "Add Comment" - end - end - - step 'I should still see a comment like "Line is correct" in the first file' do - within '.files [id^=diff]:nth-child(1) .note-body > .note-text' do - page.should have_visible_content "Line is correct" - end - end - - step 'I unfold diff' do - first('.js-unfold').click - end - - step 'I should see additional file lines' do - expect(first('.text-file')).to have_content('.bundle') - end - - step 'I click Side-by-side Diff tab' do - find('a', text: 'Side-by-side').trigger('click') - end - - step 'I should see comments on the side-by-side diff page' do - within '.files [id^=diff]:nth-child(1) .parallel .note-body > .note-text' do - page.should have_visible_content "Line is correct" - end - end - - step 'I fill in merge request search with "Fe"' do - fill_in 'issue_search', with: "Fe" - end - - def merge_request - @merge_request ||= MergeRequest.find_by!(title: "Bug NS-05") - end - - def init_diff_note - click_diff_line(sample_commit.line_code) - end - - def leave_comment(message) - within(".js-discussion-note-form") do - fill_in "note_note", with: message - click_button "Add Comment" - end - - page.should have_content message - end - - def init_diff_note_first_file - click_diff_line(sample_compare.changes[0][:line_code]) - end - - def init_diff_note_second_file - click_diff_line(sample_compare.changes[1][:line_code]) - end - - def have_visible_content (text) - have_css("*", text: text, visible: true) - end -end diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb deleted file mode 100644 index a15688ace6aef3f4ab15ccc3e3ab51553fb4b142..0000000000000000000000000000000000000000 --- a/features/steps/project/network_graph.rb +++ /dev/null @@ -1,93 +0,0 @@ -class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'page should have network graph' do - page.should have_selector ".network-graph" - end - - When 'I visit project "Shop" network page' do - # Stub Graph max_size to speed up test (10 commits vs. 650) - Network::Graph.stub(max_count: 10) - - project = Project.find_by(name: "Shop") - visit namespace_project_network_path(project.namespace, project, "master") - end - - step 'page should select "master" in select box' do - page.should have_selector '.select2-chosen', text: "master" - end - - step 'page should select "v1.0.0" in select box' do - page.should have_selector '.select2-chosen', text: "v1.0.0" - end - - step 'page should have "master" on graph' do - within '.network-graph' do - page.should have_content 'master' - end - end - - When 'I switch ref to "feature"' do - select 'feature', from: 'ref' - sleep 2 - end - - When 'I switch ref to "v1.0.0"' do - select 'v1.0.0', from: 'ref' - sleep 2 - end - - When 'click "Show only selected branch" checkbox' do - find('#filter_ref').click - sleep 2 - end - - step 'page should have content not containing "v1.0.0"' do - within '.network-graph' do - page.should have_content 'Change some files' - end - end - - step 'page should not have content not containing "v1.0.0"' do - within '.network-graph' do - page.should_not have_content 'Change some files' - end - end - - step 'page should select "feature" in select box' do - page.should have_selector '.select2-chosen', text: "feature" - end - - step 'page should select "v1.0.0" in select box' do - page.should have_selector '.select2-chosen', text: "v1.0.0" - end - - step 'page should have "feature" on graph' do - within '.network-graph' do - page.should have_content 'feature' - end - end - - When 'I looking for a commit by SHA of "v1.0.0"' do - within ".network-form" do - fill_in 'extended_sha1', with: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' - find('button').click - end - sleep 2 - end - - step 'page should have "v1.0.0" on graph' do - within '.network-graph' do - page.should have_content 'v1.0.0' - end - end - - When 'I look for a commit by ";"' do - within ".network-form" do - fill_in 'extended_sha1', with: ';' - find('button').click - end - end -end diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb deleted file mode 100644 index d39c8e7d2db82d10935ce52e5b06aa716c080db0..0000000000000000000000000000000000000000 --- a/features/steps/project/project.rb +++ /dev/null @@ -1,97 +0,0 @@ -class Spinach::Features::Project < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'change project settings' do - fill_in 'project_name_edit', with: 'NewName' - uncheck 'project_issues_enabled' - end - - step 'I save project' do - click_button 'Save changes' - end - - step 'I should see project with new settings' do - find_field('project_name').value.should == 'NewName' - end - - step 'change project path settings' do - fill_in 'project_path', with: 'new-path' - click_button 'Rename' - end - - step 'I should see project with new path settings' do - project.path.should == 'new-path' - end - - step 'I change the project avatar' do - attach_file( - :project_avatar, - File.join(Rails.root, 'public', 'gitlab_logo.png') - ) - click_button 'Save changes' - @project.reload - end - - step 'I should see new project avatar' do - @project.avatar.should be_instance_of AvatarUploader - url = @project.avatar.url - url.should == "/uploads/project/avatar/#{ @project.id }/gitlab_logo.png" - end - - step 'I should see the "Remove avatar" button' do - page.should have_link('Remove avatar') - end - - step 'I have an project avatar' do - attach_file( - :project_avatar, - File.join(Rails.root, 'public', 'gitlab_logo.png') - ) - click_button 'Save changes' - @project.reload - end - - step 'I remove my project avatar' do - click_link 'Remove avatar' - @project.reload - end - - step 'I should see the default project avatar' do - @project.avatar?.should be_false - end - - step 'I should not see the "Remove avatar" button' do - page.should_not have_link('Remove avatar') - end - - step 'I should see project "Shop" version' do - within '.project-side' do - page.should have_content 'Version: 6.7.0.pre' - end - end - - step 'change project default branch' do - select 'fix', from: 'project_default_branch' - click_button 'Save changes' - end - - step 'I should see project default branch changed' do - find(:css, 'select#project_default_branch').value.should == 'fix' - end - - step 'I select project "Forum" README tab' do - click_link 'Readme' - end - - step 'I should see project "Forum" README' do - page.should have_link 'README.md' - page.should have_content 'Sample repo for testing gitlab features' - end - - step 'I should see project "Shop" README' do - page.should have_link 'README.md' - page.should have_content 'testme' - end -end diff --git a/features/steps/project/project_shortcuts.rb b/features/steps/project/project_shortcuts.rb deleted file mode 100644 index a10e7bf78ee1fd20ca0ed3d5f4294d6e57e29ef3..0000000000000000000000000000000000000000 --- a/features/steps/project/project_shortcuts.rb +++ /dev/null @@ -1,36 +0,0 @@ -class Spinach::Features::ProjectShortcuts < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - include SharedProjectTab - - step 'I press "g" and "f"' do - find('body').native.send_key('g') - find('body').native.send_key('f') - end - - step 'I press "g" and "c"' do - find('body').native.send_key('g') - find('body').native.send_key('c') - end - - step 'I press "g" and "n"' do - find('body').native.send_key('g') - find('body').native.send_key('n') - end - - step 'I press "g" and "g"' do - find('body').native.send_key('g') - find('body').native.send_key('g') - end - - step 'I press "g" and "s"' do - find('body').native.send_key('g') - find('body').native.send_key('s') - end - - step 'I press "g" and "w"' do - find('body').native.send_key('g') - find('body').native.send_key('w') - end -end diff --git a/features/steps/project/redirects.rb b/features/steps/project/redirects.rb deleted file mode 100644 index 57c6e39c80198e49ba25da6cd889f65b4a4936e3..0000000000000000000000000000000000000000 --- a/features/steps/project/redirects.rb +++ /dev/null @@ -1,69 +0,0 @@ -class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'public project "Community"' do - create :project, :public, name: 'Community' - end - - step 'private project "Enterprise"' do - create :project, name: 'Enterprise' - end - - step 'I visit project "Community" page' do - project = Project.find_by(name: 'Community') - visit namespace_project_path(project.namespace, project) - end - - step 'I should see project "Community" home page' do - Gitlab.config.gitlab.should_receive(:host).and_return("www.example.com") - within '.navbar-gitlab .title' do - page.should have_content 'Community' - end - end - - step 'I visit project "Enterprise" page' do - project = Project.find_by(name: 'Enterprise') - visit namespace_project_path(project.namespace, project) - end - - step 'I visit project "CommunityDoesNotExist" page' do - project = Project.find_by(name: 'Community') - visit namespace_project_path(project.namespace, project) + 'DoesNotExist' - end - - step 'I click on "Sign In"' do - first(:link, "Sign in").click - end - - step 'Authenticate' do - admin = create(:admin) - project = Project.find_by(name: 'Community') - fill_in "user_login", with: admin.email - fill_in "user_password", with: admin.password - click_button "Sign in" - Thread.current[:current_user] = admin - end - - step 'I should be redirected to "Community" page' do - project = Project.find_by(name: 'Community') - current_path.should == "/#{project.path_with_namespace}" - status_code.should == 200 - end - - step 'I get redirected to signin page where I sign in' do - admin = create(:admin) - project = Project.find_by(name: 'Enterprise') - fill_in "user_login", with: admin.email - fill_in "user_password", with: admin.password - click_button "Sign in" - Thread.current[:current_user] = admin - end - - step 'I should be redirected to "Enterprise" page' do - project = Project.find_by(name: 'Enterprise') - current_path.should == "/#{project.path_with_namespace}" - status_code.should == 200 - end -end diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb deleted file mode 100644 index 4b3d79324ab62facffa21048e6f2165a3c4b09c5..0000000000000000000000000000000000000000 --- a/features/steps/project/services.rb +++ /dev/null @@ -1,225 +0,0 @@ -class Spinach::Features::ProjectServices < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I visit project "Shop" services page' do - visit namespace_project_services_path(@project.namespace, @project) - end - - step 'I should see list of available services' do - page.should have_content 'Project services' - page.should have_content 'Campfire' - page.should have_content 'HipChat' - page.should have_content 'GitLab CI' - page.should have_content 'Assembla' - page.should have_content 'Pushover' - page.should have_content 'Atlassian Bamboo' - page.should have_content 'JetBrains TeamCity' - page.should have_content 'Asana' - page.should have_content 'Irker (IRC gateway)' - end - - step 'I click gitlab-ci service link' do - click_link 'GitLab CI' - end - - step 'I fill gitlab-ci settings' do - check 'Active' - fill_in 'Project url', with: 'http://ci.gitlab.org/projects/3' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see service settings saved' do - find_field('Project url').value.should == 'http://ci.gitlab.org/projects/3' - end - - step 'I click hipchat service link' do - click_link 'HipChat' - end - - step 'I fill hipchat settings' do - check 'Active' - fill_in 'Room', with: 'gitlab' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see hipchat service settings saved' do - find_field('Room').value.should == 'gitlab' - end - - step 'I fill hipchat settings with custom server' do - check 'Active' - fill_in 'Room', with: 'gitlab_custom' - fill_in 'Token', with: 'secretCustom' - fill_in 'Server', with: 'https://chat.example.com' - click_button 'Save' - end - - step 'I should see hipchat service settings with custom server saved' do - find_field('Server').value.should == 'https://chat.example.com' - end - - step 'I click pivotaltracker service link' do - click_link 'PivotalTracker' - end - - step 'I fill pivotaltracker settings' do - check 'Active' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see pivotaltracker service settings saved' do - find_field('Token').value.should == 'verySecret' - end - - step 'I click Flowdock service link' do - click_link 'Flowdock' - end - - step 'I fill Flowdock settings' do - check 'Active' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see Flowdock service settings saved' do - find_field('Token').value.should == 'verySecret' - end - - step 'I click Assembla service link' do - click_link 'Assembla' - end - - step 'I fill Assembla settings' do - check 'Active' - fill_in 'Token', with: 'verySecret' - click_button 'Save' - end - - step 'I should see Assembla service settings saved' do - find_field('Token').value.should == 'verySecret' - end - - step 'I click Asana service link' do - click_link 'Asana' - end - - step 'I fill Asana settings' do - check 'Active' - fill_in 'Api key', with: 'verySecret' - fill_in 'Restrict to branch', with: 'master' - click_button 'Save' - end - - step 'I should see Asana service settings saved' do - find_field('Api key').value.should == 'verySecret' - find_field('Restrict to branch').value.should == 'master' - end - - step 'I click email on push service link' do - click_link 'Emails on push' - end - - step 'I fill email on push settings' do - fill_in 'Recipients', with: 'qa@company.name' - click_button 'Save' - end - - step 'I should see email on push service settings saved' do - find_field('Recipients').value.should == 'qa@company.name' - end - - step 'I click Irker service link' do - click_link 'Irker (IRC gateway)' - end - - step 'I fill Irker settings' do - check 'Active' - fill_in 'Recipients', with: 'irc://chat.freenode.net/#commits' - check 'Colorize messages' - click_button 'Save' - end - - step 'I should see Irker service settings saved' do - find_field('Recipients').value.should == 'irc://chat.freenode.net/#commits' - find_field('Colorize messages').value.should == '1' - end - - step 'I click Slack service link' do - click_link 'Slack' - end - - step 'I fill Slack settings' do - check 'Active' - fill_in 'Webhook', with: 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' - click_button 'Save' - end - - step 'I should see Slack service settings saved' do - find_field('Webhook').value.should == 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' - end - - step 'I click Pushover service link' do - click_link 'Pushover' - end - - step 'I fill Pushover settings' do - check 'Active' - fill_in 'Api key', with: 'verySecret' - fill_in 'User key', with: 'verySecret' - fill_in 'Device', with: 'myDevice' - select 'High Priority', from: 'Priority' - select 'Bike', from: 'Sound' - click_button 'Save' - end - - step 'I should see Pushover service settings saved' do - find_field('Api key').value.should == 'verySecret' - find_field('User key').value.should == 'verySecret' - find_field('Device').value.should == 'myDevice' - find_field('Priority').find('option[selected]').value.should == '1' - find_field('Sound').find('option[selected]').value.should == 'bike' - end - - step 'I click Atlassian Bamboo CI service link' do - click_link 'Atlassian Bamboo CI' - end - - step 'I fill Atlassian Bamboo CI settings' do - check 'Active' - fill_in 'Bamboo url', with: 'http://bamboo.example.com' - fill_in 'Build key', with: 'KEY' - fill_in 'Username', with: 'user' - fill_in 'Password', with: 'verySecret' - click_button 'Save' - end - - step 'I should see Atlassian Bamboo CI service settings saved' do - find_field('Bamboo url').value.should == 'http://bamboo.example.com' - find_field('Build key').value.should == 'KEY' - find_field('Username').value.should == 'user' - end - - step 'I click JetBrains TeamCity CI service link' do - click_link 'JetBrains TeamCity CI' - end - - step 'I fill JetBrains TeamCity CI settings' do - check 'Active' - fill_in 'Teamcity url', with: 'http://teamcity.example.com' - fill_in 'Build type', with: 'GitlabTest_Build' - fill_in 'Username', with: 'user' - fill_in 'Password', with: 'verySecret' - click_button 'Save' - end - - step 'I should see JetBrains TeamCity CI service settings saved' do - find_field('Teamcity url').value.should == 'http://teamcity.example.com' - find_field('Build type').value.should == 'GitlabTest_Build' - find_field('Username').value.should == 'user' - end -end diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb deleted file mode 100644 index 343aeb53b11e4d274dd63876a535c83916e4e95b..0000000000000000000000000000000000000000 --- a/features/steps/project/snippets.rb +++ /dev/null @@ -1,95 +0,0 @@ -class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - - step 'project "Shop" have "Snippet one" snippet' do - create(:project_snippet, - title: "Snippet one", - content: "Test content", - file_name: "snippet.rb", - project: project, - author: project.users.first) - end - - step 'project "Shop" have no "Snippet two" snippet' do - create(:snippet, - title: "Snippet two", - content: "Test content", - file_name: "snippet.rb", - author: project.users.first) - end - - step 'I click link "New Snippet"' do - click_link "Add new snippet" - end - - step 'I click link "Snippet one"' do - click_link "Snippet one" - end - - step 'I should see "Snippet one" in snippets' do - page.should have_content "Snippet one" - end - - step 'I should not see "Snippet two" in snippets' do - page.should_not have_content "Snippet two" - end - - step 'I should not see "Snippet one" in snippets' do - page.should_not have_content "Snippet one" - end - - step 'I click link "Edit"' do - within ".file-title" do - click_link "Edit" - end - end - - step 'I click link "Remove Snippet"' do - click_link "remove" - end - - step 'I submit new snippet "Snippet three"' do - fill_in "project_snippet_title", :with => "Snippet three" - fill_in "project_snippet_file_name", :with => "my_snippet.rb" - within('.file-editor') do - find(:xpath, "//input[@id='project_snippet_content']").set 'Content of snippet three' - end - click_button "Create snippet" - end - - step 'I should see snippet "Snippet three"' do - page.should have_content "Snippet three" - page.should have_content "Content of snippet three" - end - - step 'I submit new title "Snippet new title"' do - fill_in "project_snippet_title", :with => "Snippet new title" - click_button "Save" - end - - step 'I should see "Snippet new title"' do - page.should have_content "Snippet new title" - end - - step 'I leave a comment like "Good snippet!"' do - within('.js-main-target-form') do - fill_in "note_note", with: "Good snippet!" - click_button "Add Comment" - end - end - - step 'I should see comment "Good snippet!"' do - page.should have_content "Good snippet!" - end - - step 'I visit snippet page "Snippet one"' do - visit namespace_project_snippet_path(project.namespace, project, project_snippet) - end - - def project_snippet - @project_snippet ||= ProjectSnippet.find_by!(title: "Snippet one") - end -end diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb deleted file mode 100644 index caf6c73ee066536790c090002118654fe016e839..0000000000000000000000000000000000000000 --- a/features/steps/project/source/browse_files.rb +++ /dev/null @@ -1,218 +0,0 @@ -class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include RepoHelpers - - step 'I should see files from repository' do - page.should have_content "VERSION" - page.should have_content ".gitignore" - page.should have_content "LICENSE" - end - - step 'I should see files from repository for "6d39438"' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "6d39438") - page.should have_content ".gitignore" - page.should have_content "LICENSE" - end - - step 'I see the ".gitignore"' do - page.should have_content '.gitignore' - end - - step 'I don\'t see the ".gitignore"' do - page.should_not have_content '.gitignore' - end - - step 'I click on ".gitignore" file in repo' do - click_link ".gitignore" - end - - step 'I should see its content' do - page.should have_content old_gitignore_content - end - - step 'I should see its new content' do - page.should have_content new_gitignore_content - end - - step 'I click link "Raw"' do - click_link 'Raw' - end - - step 'I should see raw file content' do - source.should == sample_blob.data - end - - step 'I click button "Edit"' do - click_link 'Edit' - end - - step 'I cannot see the edit button' do - page.should_not have_link 'edit' - end - - step 'The edit button is disabled' do - page.should have_css '.disabled', text: 'Edit' - end - - step 'I can edit code' do - set_new_content - evaluate_script('blob.editor.getValue()').should == new_gitignore_content - end - - step 'I edit code' do - set_new_content - end - - step 'I fill the new file name' do - fill_in :file_name, with: new_file_name - end - - step 'I fill the new branch name' do - fill_in :new_branch, with: 'new_branch_name' - end - - step 'I fill the new file name with an illegal name' do - fill_in :file_name, with: 'Spaces Not Allowed' - end - - step 'I fill the commit message' do - fill_in :commit_message, with: 'Not yet a commit message.' - end - - step 'I click link "Diff"' do - click_link 'Preview changes' - end - - step 'I click on "Commit Changes"' do - click_button 'Commit Changes' - end - - step 'I click on "Remove"' do - click_button 'Remove' - end - - step 'I click on "Remove file"' do - click_button 'Remove file' - end - - step 'I see diff' do - page.should have_css '.line_holder.new' - end - - step 'I click on "new file" link in repo' do - click_link 'new-file-link' - end - - step 'I can see new file page' do - page.should have_content "New file" - page.should have_content "Commit message" - end - - step 'I click on files directory' do - click_link 'files' - end - - step 'I click on History link' do - click_link 'History' - end - - step 'I see Browse dir link' do - page.should have_link 'Browse Dir »' - page.should_not have_link 'Browse Code »' - end - - step 'I click on readme file' do - within '.tree-table' do - click_link 'README.md' - end - end - - step 'I see Browse file link' do - page.should have_link 'Browse File »' - page.should_not have_link 'Browse Code »' - end - - step 'I see Browse code link' do - page.should have_link 'Browse Code »' - page.should_not have_link 'Browse File »' - page.should_not have_link 'Browse Dir »' - end - - step 'I click on Permalink' do - click_link 'Permalink' - end - - step 'I am redirected to the files URL' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, 'master') - end - - step 'I am redirected to the ".gitignore"' do - expect(current_path).to eq(namespace_project_blob_path(@project.namespace, @project, 'master/.gitignore')) - end - - step 'I am redirected to the ".gitignore" on new branch' do - expect(current_path).to eq(namespace_project_blob_path(@project.namespace, @project, 'new_branch_name/.gitignore')) - end - - step 'I am redirected to the permalink URL' do - expect(current_path).to( - eq(namespace_project_blob_path(@project.namespace, @project, - @project.repository.commit.sha + - '/.gitignore')) - ) - end - - step 'I am redirected to the new file' do - expect(current_path).to eq(namespace_project_blob_path( - @project.namespace, @project, 'master/' + new_file_name)) - end - - step 'I am redirected to the new file on new branch' do - expect(current_path).to eq(namespace_project_blob_path( - @project.namespace, @project, 'new_branch_name/' + new_file_name)) - end - - step "I don't see the permalink link" do - expect(page).not_to have_link('permalink') - end - - step 'I see a commit error message' do - expect(page).to have_content('Your changes could not be committed') - end - - step 'I create bare repo' do - click_link 'Create empty bare repository' - end - - step 'I click on "add a file" link' do - click_link 'add a file' - - # Remove pre-receive hook so we can push without auth - FileUtils.rm_f(File.join(@project.repository.path, 'hooks', 'pre-receive')) - end - - private - - def set_new_content - execute_script("blob.editor.setValue('#{new_gitignore_content}')") - end - - # Content of the gitignore file on the seed repository. - def old_gitignore_content - '*.rbc' - end - - # Constant value that differs from the content - # of the gitignore of the seed repository. - def new_gitignore_content - old_gitignore_content + 'a' - end - - # Constant value that is a valid filename and - # not a filename present at root of the seed repository. - def new_file_name - 'not_a_file.md' - end -end diff --git a/features/steps/project/source/git_blame.rb b/features/steps/project/source/git_blame.rb deleted file mode 100644 index e29a816c51b79075ac30f1f40b75c3cf9784395c..0000000000000000000000000000000000000000 --- a/features/steps/project/source/git_blame.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Spinach::Features::ProjectSourceGitBlame < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I click on ".gitignore" file in repo' do - click_link ".gitignore" - end - - step 'I click Blame button' do - click_link 'Blame' - end - - step 'I should see git file blame' do - page.should have_content "*.rb" - page.should have_content "Dmitriy Zaporozhets" - page.should have_content "Initial commit" - end -end diff --git a/features/steps/project/source/markdown_render.rb b/features/steps/project/source/markdown_render.rb deleted file mode 100644 index 7961fdedad8a906ca70e66c0f186ff2520936804..0000000000000000000000000000000000000000 --- a/features/steps/project/source/markdown_render.rb +++ /dev/null @@ -1,288 +0,0 @@ -# If you need to modify the existing seed repository for your tests, -# it is recommended that you make the changes on the `markdown` branch of the seed project repository, -# which should only be used by tests in this file. See `/spec/factories.rb#project` for more info. -class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedMarkdown - - step 'I own project "Delta"' do - @project = Project.find_by(name: "Delta") - @project ||= create(:project, name: "Delta", namespace: @user.namespace) - @project.team << [@user, :master] - end - - step 'I should see files from repository in markdown' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown") - page.should have_content "README.md" - page.should have_content "CHANGELOG" - end - - step 'I should see rendered README which contains correct links' do - page.should have_content "Welcome to GitLab GitLab is a free project and repository management application" - page.should have_link "GitLab API doc" - page.should have_link "GitLab API website" - page.should have_link "Rake tasks" - page.should have_link "backup and restore procedure" - page.should have_link "GitLab API doc directory" - page.should have_link "Maintenance" - end - - step 'I click on Gitlab API in README' do - click_link "GitLab API doc" - end - - step 'I should see correct document rendered' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") - page.should have_content "All API requests require authentication" - end - - step 'I click on Rake tasks in README' do - click_link "Rake tasks" - end - - step 'I should see correct directory rendered' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" - end - - step 'I click on GitLab API doc directory in README' do - click_link "GitLab API doc directory" - end - - step 'I should see correct doc/api directory rendered' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") - page.should have_content "README.md" - page.should have_content "users.md" - end - - step 'I click on Maintenance in README' do - click_link "Maintenance" - end - - step 'I should see correct maintenance file rendered' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/raketasks/maintenance.md") - page.should have_content "bundle exec rake gitlab:env:info RAILS_ENV=production" - end - - step 'I click on link "empty" in the README' do - within('.readme-holder') do - click_link "empty" - end - end - - step 'I click on link "id" in the README' do - within('.readme-holder') do - click_link "#id" - end - end - - step 'I navigate to the doc/api/README' do - within '.tree-table' do - click_link "doc" - end - - within '.tree-table' do - click_link "api" - end - - within '.tree-table' do - click_link "README.md" - end - end - - step 'I see correct file rendered' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") - page.should have_content "Contents" - page.should have_link "Users" - page.should have_link "Rake tasks" - end - - step 'I click on users in doc/api/README' do - click_link "Users" - end - - step 'I should see the correct document file' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") - page.should have_content "Get a list of users." - end - - step 'I click on raketasks in doc/api/README' do - click_link "Rake tasks" - end - - # Markdown branch - - When 'I visit markdown branch' do - visit namespace_project_tree_path(@project.namespace, @project, "markdown") - end - - When 'I visit markdown branch "README.md" blob' do - visit namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") - end - - When 'I visit markdown branch "d" tree' do - visit namespace_project_tree_path(@project.namespace, @project, "markdown/d") - end - - When 'I visit markdown branch "d/README.md" blob' do - visit namespace_project_blob_path(@project.namespace, @project, "markdown/d/README.md") - end - - step 'I should see files from repository in markdown branch' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown") - page.should have_content "README.md" - page.should have_content "CHANGELOG" - end - - step 'I see correct file rendered in markdown branch' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") - page.should have_content "Contents" - page.should have_link "Users" - page.should have_link "Rake tasks" - end - - step 'I should see correct document rendered for markdown branch' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") - page.should have_content "All API requests require authentication" - end - - step 'I should see correct directory rendered for markdown branch' do - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown/doc/raketasks") - page.should have_content "backup_restore.md" - page.should have_content "maintenance.md" - end - - step 'I should see the users document file in markdown branch' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") - page.should have_content "Get a list of users." - end - - # Expected link contents - - step 'The link with text "empty" should have url "tree/markdown"' do - find('a', text: /^empty$/)['href'] == current_host + namespace_project_tree_path(@project.namespace, @project, "markdown") - end - - step 'The link with text "empty" should have url "blob/markdown/README.md"' do - find('a', text: /^empty$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") - end - - step 'The link with text "empty" should have url "tree/markdown/d"' do - find('a', text: /^empty$/)['href'] == current_host + namespace_project_tree_path(@project.namespace, @project, "markdown/d") - end - - step 'The link with text "empty" should have '\ - 'url "blob/markdown/d/README.md"' do - find('a', text: /^empty$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/d/README.md") - end - - step 'The link with text "ID" should have url "tree/markdownID"' do - find('a', text: /^#id$/)['href'] == current_host + namespace_project_tree_path(@project.namespace, @project, "markdown") + '#id' - end - - step 'The link with text "/ID" should have url "tree/markdownID"' do - find('a', text: /^\/#id$/)['href'] == current_host + namespace_project_tree_path(@project.namespace, @project, "markdown") + '#id' - end - - step 'The link with text "README.mdID" '\ - 'should have url "blob/markdown/README.mdID"' do - find('a', text: /^README.md#id$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") + '#id' - end - - step 'The link with text "d/README.mdID" should have '\ - 'url "blob/markdown/d/README.mdID"' do - find('a', text: /^d\/README.md#id$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "d/markdown/README.md") + '#id' - end - - step 'The link with text "ID" should have url "blob/markdown/README.mdID"' do - find('a', text: /^#id$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") + '#id' - end - - step 'The link with text "/ID" should have url "blob/markdown/README.mdID"' do - find('a', text: /^\/#id$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") + '#id' - end - - # Wiki - - step 'I go to wiki page' do - click_link "Wiki" - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "home") - end - - step 'I add various links to the wiki page' do - fill_in "wiki[content]", with: "[test](test)\n[GitLab API doc](api)\n[Rake tasks](raketasks)\n" - fill_in "wiki[message]", with: "Adding links to wiki" - click_button "Create page" - end - - step 'Wiki page should have added links' do - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "home") - page.should have_content "test GitLab API doc Rake tasks" - end - - step 'I add a header to the wiki page' do - fill_in "wiki[content]", with: "# Wiki header\n" - fill_in "wiki[message]", with: "Add header to wiki" - click_button "Create page" - end - - step 'Wiki header should have correct id and link' do - header_should_have_correct_id_and_link(1, 'Wiki header', 'wiki-header') - end - - step 'I click on test link' do - click_link "test" - end - - step 'I see new wiki page named test' do - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "test") - page.should have_content "Editing" - end - - When 'I go back to wiki page home' do - visit namespace_project_wiki_path(@project.namespace, @project, "home") - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "home") - end - - step 'I click on GitLab API doc link' do - click_link "GitLab API" - end - - step 'I see Gitlab API document' do - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "api") - page.should have_content "Editing" - end - - step 'I click on Rake tasks link' do - click_link "Rake tasks" - end - - step 'I see Rake tasks directory' do - current_path.should == namespace_project_wiki_path(@project.namespace, @project, "raketasks") - page.should have_content "Editing" - end - - step 'I go directory which contains README file' do - visit namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") - current_path.should == namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") - end - - step 'I click on a relative link in README' do - click_link "Users" - end - - step 'I should see the correct markdown' do - current_path.should == namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") - page.should have_content "List users" - end - - step 'Header "Application details" should have correct id and link' do - header_should_have_correct_id_and_link(2, 'Application details', 'application-details') - end - - step 'Header "GitLab API" should have correct id and link' do - header_should_have_correct_id_and_link(1, 'GitLab API', 'gitlab-api') - end -end diff --git a/features/steps/project/source/multiselect_blob.rb b/features/steps/project/source/multiselect_blob.rb deleted file mode 100644 index b749ba493719cbb7610e4ef0122ccb9b1caaa428..0000000000000000000000000000000000000000 --- a/features/steps/project/source/multiselect_blob.rb +++ /dev/null @@ -1,58 +0,0 @@ -class Spinach::Features::ProjectSourceMultiselectBlob < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - class << self - def click_line_steps(*line_numbers) - line_numbers.each do |line_number| - step "I click line #{line_number} in file" do - find("#L#{line_number}").click - end - - step "I shift-click line #{line_number} in file" do - script = "$('#L#{line_number}').trigger($.Event('click', { shiftKey: true }));" - execute_script(script) - end - end - end - - def check_state_steps(*ranges) - ranges.each do |range| - fragment = range.kind_of?(Array) ? "L#{range.first}-#{range.last}" : "L#{range}" - pluralization = range.kind_of?(Array) ? "s" : "" - - step "I should see \"#{fragment}\" as URI fragment" do - URI.parse(current_url).fragment.should == fragment - end - - step "I should see line#{pluralization} #{fragment[1..-1]} highlighted" do - ids = Array(range).map { |n| "LC#{n}" } - extra = false - - highlighted = all("#tree-content-holder .highlight .line.hll") - highlighted.each do |element| - extra ||= ids.delete(element[:id]).nil? - end - - extra.should be_false and ids.should be_empty - end - end - end - end - - click_line_steps *Array(1..5) - check_state_steps *Array(1..5), Array(1..2), Array(1..3), Array(1..4), Array(1..5), Array(3..5) - - step 'I go back in history' do - go_back - end - - step 'I go forward in history' do - go_forward - end - - step 'I click on ".gitignore" file in repo' do - click_link ".gitignore" - end -end diff --git a/features/steps/project/source/search_code.rb b/features/steps/project/source/search_code.rb deleted file mode 100644 index 9c2864cc93637303d0bc7a5f186c85f64a5efd60..0000000000000000000000000000000000000000 --- a/features/steps/project/source/search_code.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Spinach::Features::ProjectSourceSearchCode < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - - step 'I search for term "coffee"' do - fill_in "search", with: "coffee" - click_button "Go" - end - - step 'I should see files from repository containing "coffee"' do - page.should have_content 'coffee' - page.should have_content 'CONTRIBUTING.md' - end - - step 'I should see empty result' do - page.should have_content "We couldn't find any matching" - end -end diff --git a/features/steps/project/star.rb b/features/steps/project/star.rb deleted file mode 100644 index 50cdfd73c347501a0fcd69386f97fd8f3b376cd2..0000000000000000000000000000000000000000 --- a/features/steps/project/star.rb +++ /dev/null @@ -1,37 +0,0 @@ -class Spinach::Features::ProjectStar < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include SharedUser - - step "The project has no stars" do - page.should_not have_content '.star-buttons' - end - - step "The project has 0 stars" do - has_n_stars(0) - end - - step "The project has 1 star" do - has_n_stars(1) - end - - step "The project has 2 stars" do - has_n_stars(2) - end - - # Requires @javascript - step "I click on the star toggle button" do - find(".star-btn", visible: true).click - end - - step 'I redirected to sign in page' do - current_path.should == new_user_session_path - end - - protected - - def has_n_stars(n) - expect(page).to have_css(".star-btn .count", text: n, visible: true) - end -end diff --git a/features/steps/project/team_management.rb b/features/steps/project/team_management.rb deleted file mode 100644 index e95621071c4ca1deaced3f3b625b40a4fc40bc8d..0000000000000000000000000000000000000000 --- a/features/steps/project/team_management.rb +++ /dev/null @@ -1,130 +0,0 @@ -class Spinach::Features::ProjectTeamManagement < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedPaths - include Select2Helper - - step 'I should be able to see myself in team' do - page.should have_content(@user.name) - page.should have_content(@user.username) - end - - step 'I should see "Sam" in team list' do - user = User.find_by(name: "Sam") - page.should have_content(user.name) - page.should have_content(user.username) - end - - step 'I click link "Add members"' do - find(:css, 'button.btn-new').click - end - - step 'I select "Mike" as "Reporter"' do - user = User.find_by(name: "Mike") - - within ".users-project-form" do - select2(user.id, from: "#user_ids", multiple: true) - select "Reporter", from: "access_level" - end - click_button "Add users to project" - end - - step 'I should see "Mike" in team list as "Reporter"' do - within ".access-reporter" do - page.should have_content('Mike') - end - end - - step 'I select "sjobs@apple.com" as "Reporter"' do - within ".users-project-form" do - select2("sjobs@apple.com", from: "#user_ids", multiple: true) - select "Reporter", from: "access_level" - end - click_button "Add users to project" - end - - step 'I should see "sjobs@apple.com" in team list as invited "Reporter"' do - within ".access-reporter" do - page.should have_content('sjobs@apple.com') - page.should have_content('invited') - page.should have_content('Reporter') - end - end - - step 'I should see "Sam" in team list as "Developer"' do - within ".access-developer" do - page.should have_content('Sam') - end - end - - step 'I change "Sam" role to "Reporter"' do - project = Project.find_by(name: "Shop") - user = User.find_by(name: 'Sam') - project_member = project.project_members.find_by(user_id: user.id) - within "#project_member_#{project_member.id}" do - click_button "Edit access level" - select "Reporter", from: "project_member_access_level" - click_button "Save" - end - end - - step 'I should see "Sam" in team list as "Reporter"' do - within ".access-reporter" do - page.should have_content('Sam') - end - end - - step 'I click link "Remove from team"' do - click_link "Remove from team" - end - - step 'I should not see "Sam" in team list' do - user = User.find_by(name: "Sam") - page.should_not have_content(user.name) - page.should_not have_content(user.username) - end - - step 'gitlab user "Mike"' do - create(:user, name: "Mike") - end - - step 'gitlab user "Sam"' do - create(:user, name: "Sam") - end - - step '"Sam" is "Shop" developer' do - user = User.find_by(name: "Sam") - project = Project.find_by(name: "Shop") - project.team << [user, :developer] - end - - step 'I own project "Website"' do - @project = create(:empty_project, name: "Website", namespace: @user.namespace) - @project.team << [@user, :master] - end - - step '"Mike" is "Website" reporter' do - user = User.find_by(name: "Mike") - project = Project.find_by(name: "Website") - project.team << [user, :reporter] - end - - step 'I click link "Import team from another project"' do - click_link "Import members from another project" - end - - When 'I submit "Website" project for import team' do - project = Project.find_by(name: "Website") - select project.name_with_namespace, from: 'source_project_id' - click_button 'Import' - end - - step 'I click cancel link for "Sam"' do - project = Project.find_by(name: "Shop") - user = User.find_by(name: 'Sam') - project_member = project.project_members.find_by(user_id: user.id) - within "#project_member_#{project_member.id}" do - click_link('Remove user from team') - end - end -end diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb deleted file mode 100644 index bb93e582a1fd4b0edee183c9a6a2e0dda4d55c95..0000000000000000000000000000000000000000 --- a/features/steps/project/wiki.rb +++ /dev/null @@ -1,165 +0,0 @@ -class Spinach::Features::ProjectWiki < Spinach::FeatureSteps - include SharedAuthentication - include SharedProject - include SharedNote - include SharedPaths - include WikiHelper - - step 'I click on the Cancel button' do - within(:css, ".form-actions") do - click_on "Cancel" - end - end - - step 'I should be redirected back to the Edit Home Wiki page' do - current_path.should == namespace_project_wiki_path(project.namespace, project, :home) - end - - step 'I create the Wiki Home page' do - fill_in "wiki_content", with: '[link test](test)' - click_on "Create page" - end - - step 'I should see the newly created wiki page' do - page.should have_content "Home" - page.should have_content "link test" - - click_link "link test" - page.should have_content "Editing" - end - - step 'I have an existing Wiki page' do - wiki.create_page("existing", "content", :markdown, "first commit") - @page = wiki.find_page("existing") - end - - step 'I browse to that Wiki page' do - visit namespace_project_wiki_path(project.namespace, project, @page) - end - - step 'I click on the Edit button' do - click_on "Edit" - end - - step 'I change the content' do - fill_in "Content", with: 'Updated Wiki Content' - click_on "Save changes" - end - - step 'I should see the updated content' do - page.should have_content "Updated Wiki Content" - end - - step 'I should be redirected back to that Wiki page' do - current_path.should == namespace_project_wiki_path(project.namespace, project, @page) - end - - step 'That page has two revisions' do - @page.update("new content", :markdown, "second commit") - end - - step 'I click the History button' do - click_on "History" - end - - step 'I should see both revisions' do - page.should have_content current_user.name - page.should have_content "first commit" - page.should have_content "second commit" - end - - step 'I click on the "Delete this page" button' do - click_on "Delete this page" - end - - step 'The page should be deleted' do - page.should have_content "Page was successfully deleted" - end - - step 'I click on the "Pages" button' do - click_on "Pages" - end - - step 'I should see the existing page in the pages list' do - page.should have_content current_user.name - page.should have_content @page.title - end - - step 'I have an existing Wiki page with images linked on page' do - wiki.create_page("pictures", "Look at this [image](image.jpg)\n\n ![image](image.jpg)", :markdown, "first commit") - @wiki_page = wiki.find_page("pictures") - end - - step 'I browse to wiki page with images' do - visit namespace_project_wiki_path(project.namespace, project, @wiki_page) - end - - step 'I click on existing image link' do - file = Gollum::File.new(wiki.wiki) - Gollum::Wiki.any_instance.stub(:file).with("image.jpg", "master", true).and_return(file) - Gollum::File.any_instance.stub(:mime_type).and_return("image/jpeg") - page.should have_link('image', href: "image.jpg") - click_on "image" - end - - step 'I should see the image from wiki repo' do - current_path.should match('wikis/image.jpg') - page.should_not have_xpath('/html') # Page should render the image which means there is no html involved - Gollum::Wiki.any_instance.unstub(:file) - Gollum::File.any_instance.unstub(:mime_type) - end - - step 'Image should be shown on the page' do - page.should have_xpath("//img[@src=\"image.jpg\"]") - end - - step 'I click on image link' do - page.should have_link('image', href: "image.jpg") - click_on "image" - end - - step 'I should see the new wiki page form' do - current_path.should match('wikis/image.jpg') - page.should have_content('New Wiki Page') - page.should have_content('Editing - image.jpg') - end - - step 'I create a New page with paths' do - click_on 'New Page' - fill_in 'Page slug', with: 'one/two/three' - click_on 'Build' - fill_in "wiki_content", with: 'wiki content' - click_on "Create page" - current_path.should include 'one/two/three' - end - - step 'I should see non-escaped link in the pages list' do - page.should have_xpath("//a[@href='/#{project.path_with_namespace}/wikis/one/two/three']") - end - - step 'I edit the Wiki page with a path' do - click_on 'three' - click_on 'Edit' - end - - step 'I should see a non-escaped path' do - current_path.should include 'one/two/three' - end - - step 'I should see the Editing page' do - page.should have_content('Editing') - end - - step 'I view the page history of a Wiki page that has a path' do - click_on 'three' - click_on 'Page History' - end - - step 'I should see the page history' do - page.should have_content('History for') - end - - def wiki - @project_wiki = ProjectWiki.new(project, current_user) - end -end diff --git a/features/steps/search.rb b/features/steps/search.rb deleted file mode 100644 index 6f0e038c4d6332eb486948f893293f4cd7a485cf..0000000000000000000000000000000000000000 --- a/features/steps/search.rb +++ /dev/null @@ -1,69 +0,0 @@ -class Spinach::Features::Search < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I search for "Sho"' do - fill_in "dashboard_search", with: "Sho" - click_button "Search" - end - - step 'I search for "Foo"' do - fill_in "dashboard_search", with: "Foo" - click_button "Search" - end - - step 'I search for "rspec"' do - fill_in "dashboard_search", with: "rspec" - click_button "Search" - end - - step 'I click "Issues" link' do - within '.search-filter' do - click_link 'Issues' - end - end - - step 'I click project "Shop" link' do - within '.project-filter' do - click_link project.name_with_namespace - end - end - - step 'I click "Merge requests" link' do - within '.search-filter' do - click_link 'Merge requests' - end - end - - step 'I should see "Shop" project link' do - page.should have_link "Shop" - end - - step 'I should see code results for project "Shop"' do - page.should have_content 'Update capybara, rspec-rails, poltergeist to recent versions' - end - - step 'I search for "Contibuting"' do - fill_in "dashboard_search", with: "Contibuting" - click_button "Search" - end - - step 'project has issues' do - create(:issue, title: "Foo", project: project) - create(:issue, title: "Bar", project: project) - end - - step 'project has merge requests' do - create(:merge_request, title: "Foo", source_project: project, target_project: project) - create(:merge_request, :simple, title: "Bar", source_project: project, target_project: project) - end - - step 'I should see "Foo" link in the search results' do - find(:css, '.search-results').should have_link 'Foo' - end - - step 'I should not see "Bar" link in the search results' do - find(:css, '.search-results').should_not have_link 'Bar' - end -end diff --git a/features/steps/shared/active_tab.rb b/features/steps/shared/active_tab.rb deleted file mode 100644 index 9beb688bd16c163c40063b1aefa0a196d61d7a8b..0000000000000000000000000000000000000000 --- a/features/steps/shared/active_tab.rb +++ /dev/null @@ -1,47 +0,0 @@ -module SharedActiveTab - include Spinach::DSL - - def ensure_active_main_tab(content) - find('.nav-sidebar > li.active').should have_content(content) - end - - def ensure_active_sub_tab(content) - find('div.content ul.nav-tabs li.active').should have_content(content) - end - - def ensure_active_sub_nav(content) - find('.sidebar-subnav > li.active').should have_content(content) - end - - step 'no other main tabs should be active' do - page.should have_selector('.nav-sidebar > li.active', count: 1) - end - - step 'no other sub tabs should be active' do - page.should have_selector('div.content ul.nav-tabs li.active', count: 1) - end - - step 'no other sub navs should be active' do - page.should have_selector('.sidebar-subnav > li.active', count: 1) - end - - step 'the active main tab should be Home' do - ensure_active_main_tab('Your Projects') - end - - step 'the active main tab should be Projects' do - ensure_active_main_tab('Projects') - end - - step 'the active main tab should be Issues' do - ensure_active_main_tab('Issues') - end - - step 'the active main tab should be Merge Requests' do - ensure_active_main_tab('Merge Requests') - end - - step 'the active main tab should be Help' do - ensure_active_main_tab('Help') - end -end diff --git a/features/steps/shared/admin.rb b/features/steps/shared/admin.rb deleted file mode 100644 index b6072995677ba36198d5e67028934ff880f89c5a..0000000000000000000000000000000000000000 --- a/features/steps/shared/admin.rb +++ /dev/null @@ -1,12 +0,0 @@ -module SharedAdmin - include Spinach::DSL - - step 'there are projects in system' do - 2.times { create(:project) } - end - - step 'system has users' do - 2.times { create(:user) } - end -end - diff --git a/features/steps/shared/authentication.rb b/features/steps/shared/authentication.rb deleted file mode 100644 index ac8a3df6bb9fae52edda9318a7621b8a69952d6b..0000000000000000000000000000000000000000 --- a/features/steps/shared/authentication.rb +++ /dev/null @@ -1,34 +0,0 @@ -require Rails.root.join('spec', 'support', 'login_helpers') - -module SharedAuthentication - include Spinach::DSL - include LoginHelpers - - step 'I sign in as a user' do - login_as :user - end - - step 'I sign in as an admin' do - login_as :admin - end - - step 'I sign in as "John Doe"' do - login_with(user_exists("John Doe")) - end - - step 'I sign in as "Mary Jane"' do - login_with(user_exists("Mary Jane")) - end - - step 'I should be redirected to sign in page' do - current_path.should == new_user_session_path - end - - step "I logout" do - logout - end - - def current_user - @user || User.first - end -end diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb deleted file mode 100644 index 510e0f0f93892e94d581172a4c9d4a2fde2c1455..0000000000000000000000000000000000000000 --- a/features/steps/shared/diff_note.rb +++ /dev/null @@ -1,167 +0,0 @@ -module SharedDiffNote - include Spinach::DSL - include RepoHelpers - - step 'I cancel the diff comment' do - within(diff_file_selector) do - find(".js-close-discussion-note-form").click - end - end - - step 'I delete a diff comment' do - find('.note').hover - find(".js-note-delete").click - end - - step 'I haven\'t written any diff comment text' do - within(diff_file_selector) do - fill_in "note[note]", with: "" - end - end - - step 'I leave a diff comment like "Typo, please fix"' do - click_diff_line(sample_commit.line_code) - within("#{diff_file_selector} form[rel$='#{sample_commit.line_code}']") do - fill_in "note[note]", with: "Typo, please fix" - find(".js-comment-button").trigger("click") - sleep 0.05 - end - end - - step 'I preview a diff comment text like "Should fix it :smile:"' do - click_diff_line(sample_commit.line_code) - within("#{diff_file_selector} form[rel$='#{sample_commit.line_code}']") do - fill_in "note[note]", with: "Should fix it :smile:" - find('.js-md-preview-button').click - end - end - - step 'I preview another diff comment text like "DRY this up"' do - click_diff_line(sample_commit.del_line_code) - - within("#{diff_file_selector} form[rel$='#{sample_commit.del_line_code}']") do - fill_in "note[note]", with: "DRY this up" - find('.js-md-preview-button').click - end - end - - step 'I open a diff comment form' do - click_diff_line(sample_commit.line_code) - end - - step 'I open another diff comment form' do - click_diff_line(sample_commit.del_line_code) - end - - step 'I write a diff comment like ":-1: I don\'t like this"' do - within(diff_file_selector) do - fill_in "note[note]", with: ":-1: I don\'t like this" - end - end - - step 'I submit the diff comment' do - within(diff_file_selector) do - click_button("Add Comment") - end - end - - step 'I should not see the diff comment form' do - within(diff_file_selector) do - page.should_not have_css("form.new_note") - end - end - - step 'The diff comment preview tab should say there is nothing to do' do - within(diff_file_selector) do - find('.js-md-preview-button').click - expect(find('.js-md-preview')).to have_content('Nothing to preview.') - end - end - - step 'I should not see the diff comment text field' do - within(diff_file_selector) do - expect(find('.js-note-text')).not_to be_visible - end - end - - step 'I should only see one diff form' do - within(diff_file_selector) do - page.should have_css("form.new_note", count: 1) - end - end - - step 'I should see a diff comment form with ":-1: I don\'t like this"' do - within(diff_file_selector) do - page.should have_field("note[note]", with: ":-1: I don\'t like this") - end - end - - step 'I should see a diff comment saying "Typo, please fix"' do - within("#{diff_file_selector} .note") do - page.should have_content("Typo, please fix") - end - end - - step 'I should see a discussion reply button' do - within(diff_file_selector) do - page.should have_button('Reply') - end - end - - step 'I should see a temporary diff comment form' do - within(diff_file_selector) do - page.should have_css(".js-temp-notes-holder form.new_note") - end - end - - step 'I should see add a diff comment button' do - page.should have_css('.js-add-diff-note-button', visible: true) - end - - step 'I should see an empty diff comment form' do - within(diff_file_selector) do - page.should have_field("note[note]", with: "") - end - end - - step 'I should see the cancel comment button' do - within("#{diff_file_selector} form") do - page.should have_css(".js-close-discussion-note-form", text: "Cancel") - end - end - - step 'I should see the diff comment preview' do - within("#{diff_file_selector} form") do - expect(page).to have_css('.js-md-preview', visible: true) - end - end - - step 'I should see the diff comment write tab' do - within(diff_file_selector) do - expect(page).to have_css('.js-md-write-button', visible: true) - end - end - - step 'The diff comment preview tab should display rendered Markdown' do - within(diff_file_selector) do - find('.js-md-preview-button').click - expect(find('.js-md-preview')).to have_css('img.emoji', visible: true) - end - end - - step 'I should see two separate previews' do - within(diff_file_selector) do - expect(page).to have_css('.js-md-preview', visible: true, count: 2) - expect(page).to have_content('Should fix it') - expect(page).to have_content('DRY this up') - end - end - - def diff_file_selector - ".diff-file:nth-of-type(1)" - end - - def click_diff_line(code) - find("button[data-line-code='#{code}']").click - end -end diff --git a/features/steps/shared/group.rb b/features/steps/shared/group.rb deleted file mode 100644 index 1b225dd61a6f111a024c5447d379a35a03c53e63..0000000000000000000000000000000000000000 --- a/features/steps/shared/group.rb +++ /dev/null @@ -1,44 +0,0 @@ -module SharedGroup - include Spinach::DSL - - step '"John Doe" is owner of group "Owned"' do - is_member_of("John Doe", "Owned", Gitlab::Access::OWNER) - end - - step '"John Doe" is guest of group "Guest"' do - is_member_of("John Doe", "Guest", Gitlab::Access::GUEST) - end - - step '"Mary Jane" is owner of group "Owned"' do - is_member_of("Mary Jane", "Owned", Gitlab::Access::OWNER) - end - - step '"Mary Jane" is guest of group "Owned"' do - is_member_of("Mary Jane", "Owned", Gitlab::Access::GUEST) - end - - step '"Mary Jane" is guest of group "Guest"' do - is_member_of("Mary Jane", "Guest", Gitlab::Access::GUEST) - end - - step 'I should see group "TestGroup"' do - page.should have_content "TestGroup" - end - - step 'I should not see group "TestGroup"' do - page.should_not have_content "TestGroup" - end - - protected - - def is_member_of(username, groupname, role) - @project_count ||= 0 - user = User.find_by(name: username) || create(:user, name: username) - group = Group.find_by(name: groupname) || create(:group, name: groupname) - group.add_user(user, role) - project ||= create(:project, namespace: group, path: "project#{@project_count}") - event ||= create(:closed_issue_event, project: project) - project.team << [user, :master] - @project_count += 1 - end -end diff --git a/features/steps/shared/issuable.rb b/features/steps/shared/issuable.rb deleted file mode 100644 index 41db2612f2623f75147e4e8fc98c5cc85c0589f5..0000000000000000000000000000000000000000 --- a/features/steps/shared/issuable.rb +++ /dev/null @@ -1,15 +0,0 @@ -module SharedIssuable - include Spinach::DSL - - def edit_issuable - find(:css, '.issuable-edit').click - end - - step 'I click link "Edit" for the merge request' do - edit_issuable - end - - step 'I click link "Edit" for the issue' do - edit_issuable - end -end diff --git a/features/steps/shared/markdown.rb b/features/steps/shared/markdown.rb deleted file mode 100644 index e71700880cde96622a3a307ad47e79deaba25e80..0000000000000000000000000000000000000000 --- a/features/steps/shared/markdown.rb +++ /dev/null @@ -1,102 +0,0 @@ -module SharedMarkdown - include Spinach::DSL - - def header_should_have_correct_id_and_link(level, text, id, parent = ".wiki") - find(:css, "#{parent} h#{level}##{id}").text.should == text - find(:css, "#{parent} h#{level}##{id} > :last-child")[:href].should =~ /##{id}$/ - end - - def create_taskable(type, title) - desc_text = < .note-text") do - page.should have_content("Comment with a header") - page.should_not have_css("#comment-with-a-header") - end - end - - step 'I leave a comment with task markdown' do - within('.js-main-target-form') do - fill_in 'note[note]', with: '* [x] Task item' - click_button 'Add Comment' - sleep 0.05 - end - end - - step 'I should not see task checkboxes in the comment' do - expect(page).not_to have_selector( - 'li.note div.timeline-content input[type="checkbox"]' - ) - end - - step 'I edit the last comment with a +1' do - find(".note").hover - find('.js-note-edit').click - - within(".current-note-edit-form") do - fill_in 'note[note]', with: '+1 Awesome!' - click_button 'Save Comment' - sleep 0.05 - end - end - - step 'I should see +1 in the description' do - within(".note") do - page.should have_content("+1 Awesome!") - end - end -end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb deleted file mode 100644 index e3cf1b92cda3bb508293ace1e13fc791c57ddb32..0000000000000000000000000000000000000000 --- a/features/steps/shared/paths.rb +++ /dev/null @@ -1,480 +0,0 @@ -module SharedPaths - include Spinach::DSL - include RepoHelpers - include DashboardHelper - - step 'I visit new project page' do - visit new_project_path - end - - # ---------------------------------------- - # User - # ---------------------------------------- - - step 'I visit user "John Doe" page' do - visit user_path("john_doe") - end - - # ---------------------------------------- - # Group - # ---------------------------------------- - - step 'I visit group "Owned" page' do - visit group_path(Group.find_by(name:"Owned")) - end - - step 'I visit group "Owned" issues page' do - visit issues_group_path(Group.find_by(name:"Owned")) - end - - step 'I visit group "Owned" merge requests page' do - visit merge_requests_group_path(Group.find_by(name:"Owned")) - end - - step 'I visit group "Owned" members page' do - visit group_group_members_path(Group.find_by(name:"Owned")) - end - - step 'I visit group "Owned" settings page' do - visit edit_group_path(Group.find_by(name:"Owned")) - end - - step 'I visit group "Guest" page' do - visit group_path(Group.find_by(name:"Guest")) - end - - step 'I visit group "Guest" issues page' do - visit issues_group_path(Group.find_by(name:"Guest")) - end - - step 'I visit group "Guest" merge requests page' do - visit merge_requests_group_path(Group.find_by(name:"Guest")) - end - - step 'I visit group "Guest" members page' do - visit group_group_members_path(Group.find_by(name:"Guest")) - end - - step 'I visit group "Guest" settings page' do - visit edit_group_path(Group.find_by(name:"Guest")) - end - - # ---------------------------------------- - # Dashboard - # ---------------------------------------- - - step 'I visit dashboard page' do - visit dashboard_path - end - - step 'I visit dashboard projects page' do - visit projects_dashboard_path - end - - step 'I visit dashboard issues page' do - visit assigned_issues_dashboard_path - end - - step 'I visit dashboard merge requests page' do - visit assigned_mrs_dashboard_path - end - - step 'I visit dashboard search page' do - visit search_path - end - - step 'I visit dashboard help page' do - visit help_path - end - - step 'I visit dashboard groups page' do - visit dashboard_groups_path - end - - step 'I should be redirected to the dashboard groups page' do - current_path.should == dashboard_groups_path - end - - step 'I visit dashboard starred projects page' do - visit starred_dashboard_projects_path - end - - # ---------------------------------------- - # Profile - # ---------------------------------------- - - step 'I visit profile page' do - visit profile_path - end - - step 'I visit profile applications page' do - visit applications_profile_path - end - - step 'I visit profile password page' do - visit edit_profile_password_path - end - - step 'I visit profile account page' do - visit profile_account_path - end - - step 'I visit profile SSH keys page' do - visit profile_keys_path - end - - step 'I visit profile design page' do - visit design_profile_path - end - - step 'I visit profile history page' do - visit history_profile_path - end - - # ---------------------------------------- - # Admin - # ---------------------------------------- - - step 'I visit admin page' do - visit admin_root_path - end - - step 'I visit admin projects page' do - visit admin_namespaces_projects_path - end - - step 'I visit admin users page' do - visit admin_users_path - end - - step 'I visit admin logs page' do - visit admin_logs_path - end - - step 'I visit admin messages page' do - visit admin_broadcast_messages_path - end - - step 'I visit admin hooks page' do - visit admin_hooks_path - end - - step 'I visit admin Resque page' do - visit admin_background_jobs_path - end - - step 'I visit admin groups page' do - visit admin_groups_path - end - - step 'I visit admin teams page' do - visit admin_teams_path - end - - step 'I visit admin settings page' do - visit admin_application_settings_path - end - - step 'I visit applications page' do - visit admin_applications_path - end - - # ---------------------------------------- - # Generic Project - # ---------------------------------------- - - step "I visit my project's home page" do - visit namespace_project_path(@project.namespace, @project) - end - - step "I visit my project's settings page" do - visit edit_namespace_project_path(@project.namespace, @project) - end - - step "I visit my project's files page" do - visit namespace_project_tree_path(@project.namespace, @project, root_ref) - end - - step 'I visit a binary file in the repo' do - visit namespace_project_blob_path(@project.namespace, @project, File.join( - root_ref, 'files/images/logo-black.png')) - end - - step "I visit my project's commits page" do - visit namespace_project_commits_path(@project.namespace, @project, root_ref, {limit: 5}) - end - - step "I visit my project's commits page for a specific path" do - visit namespace_project_commits_path(@project.namespace, @project, root_ref + "/app/models/project.rb", {limit: 5}) - end - - step 'I visit my project\'s commits stats page' do - visit stats_namespace_project_repository_path(@project.namespace, @project) - end - - step "I visit my project's network page" do - # Stub Graph max_size to speed up test (10 commits vs. 650) - Network::Graph.stub(max_count: 10) - - visit namespace_project_network_path(@project.namespace, @project, root_ref) - end - - step "I visit my project's issues page" do - visit namespace_project_issues_path(@project.namespace, @project) - end - - step "I visit my project's merge requests page" do - visit namespace_project_merge_requests_path(@project.namespace, @project) - end - - step "I visit my project's wiki page" do - visit namespace_project_wiki_path(@project.namespace, @project, :home) - end - - step 'I visit project hooks page' do - visit namespace_project_hooks_path(@project.namespace, @project) - end - - step 'I visit project deploy keys page' do - visit namespace_project_deploy_keys_path(@project.namespace, @project) - end - - # ---------------------------------------- - # "Shop" Project - # ---------------------------------------- - - step 'I visit project "Shop" page' do - visit namespace_project_path(project.namespace, project) - end - - step 'I visit project "Forked Shop" merge requests page' do - visit namespace_project_merge_requests_path(@forked_project.namespace, @forked_project) - end - - step 'I visit edit project "Shop" page' do - visit edit_namespace_project_path(project.namespace, project) - end - - step 'I visit project branches page' do - visit namespace_project_branches_path(@project.namespace, @project) - end - - step 'I visit project protected branches page' do - visit namespace_project_protected_branches_path(@project.namespace, @project) - end - - step 'I visit compare refs page' do - visit namespace_project_compare_index_path(@project.namespace, @project) - end - - step 'I visit project commits page' do - visit namespace_project_commits_path(@project.namespace, @project, root_ref, {limit: 5}) - end - - step 'I visit project commits page for stable branch' do - visit namespace_project_commits_path(@project.namespace, @project, 'stable', {limit: 5}) - end - - step 'I visit project source page' do - visit namespace_project_tree_path(@project.namespace, @project, root_ref) - end - - step 'I visit blob file from repo' do - visit namespace_project_blob_path(@project.namespace, @project, File.join(sample_commit.id, sample_blob.path)) - end - - step 'I visit ".gitignore" file in repo' do - visit namespace_project_blob_path(@project.namespace, @project, File.join(root_ref, '.gitignore')) - end - - step 'I am on the new file page' do - current_path.should eq(namespace_project_create_blob_path(@project.namespace, @project, root_ref)) - end - - step 'I am on the ".gitignore" edit file page' do - current_path.should eq(namespace_project_edit_blob_path( - @project.namespace, @project, File.join(root_ref, '.gitignore'))) - end - - step 'I visit project source page for "6d39438"' do - visit namespace_project_tree_path(@project.namespace, @project, "6d39438") - end - - step 'I visit project source page for' \ - ' "6d394385cf567f80a8fd85055db1ab4c5295806f"' do - visit namespace_project_tree_path(@project.namespace, @project, - '6d394385cf567f80a8fd85055db1ab4c5295806f') - end - - step 'I visit project tags page' do - visit namespace_project_tags_path(@project.namespace, @project) - end - - step 'I visit project commit page' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.id) - end - - step 'I visit project "Shop" issues page' do - visit namespace_project_issues_path(project.namespace, project) - end - - step 'I visit issue page "Release 0.4"' do - issue = Issue.find_by(title: "Release 0.4") - visit namespace_project_issue_path(issue.project.namespace, issue.project, issue) - end - - step 'I visit issue page "Tasks-open"' do - issue = Issue.find_by(title: 'Tasks-open') - visit namespace_project_issue_path(issue.project.namespace, issue.project, issue) - end - - step 'I visit issue page "Tasks-closed"' do - issue = Issue.find_by(title: 'Tasks-closed') - visit namespace_project_issue_path(issue.project.namespace, issue.project, issue) - end - - step 'I visit project "Shop" labels page' do - project = Project.find_by(name: 'Shop') - visit namespace_project_labels_path(project.namespace, project) - end - - step 'I visit project "Forum" labels page' do - project = Project.find_by(name: 'Forum') - visit namespace_project_labels_path(project.namespace, project) - end - - step 'I visit project "Shop" new label page' do - project = Project.find_by(name: 'Shop') - visit new_namespace_project_label_path(project.namespace, project) - end - - step 'I visit project "Forum" new label page' do - project = Project.find_by(name: 'Forum') - visit new_namespace_project_label_path(project.namespace, project) - end - - step 'I visit merge request page "Bug NS-04"' do - mr = MergeRequest.find_by(title: "Bug NS-04") - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) - end - - step 'I visit merge request page "Bug NS-05"' do - mr = MergeRequest.find_by(title: "Bug NS-05") - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) - end - - step 'I visit merge request page "MR-task-open"' do - mr = MergeRequest.find_by(title: 'MR-task-open') - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) - end - - step 'I visit merge request page "MR-task-closed"' do - mr = MergeRequest.find_by(title: 'MR-task-closed') - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) - end - - step 'I visit project "Shop" merge requests page' do - visit namespace_project_merge_requests_path(project.namespace, project) - end - - step 'I visit forked project "Shop" merge requests page' do - visit namespace_project_merge_requests_path(project.namespace, project) - end - - step 'I visit project "Shop" milestones page' do - visit namespace_project_milestones_path(project.namespace, project) - end - - step 'I visit project "Shop" team page' do - visit namespace_project_project_members_path(project.namespace, project) - end - - step 'I visit project wiki page' do - visit namespace_project_wiki_path(@project.namespace, @project, :home) - end - - # ---------------------------------------- - # Visibility Projects - # ---------------------------------------- - - step 'I visit project "Community" page' do - project = Project.find_by(name: "Community") - visit namespace_project_path(project.namespace, project) - end - - step 'I visit project "Community" source page' do - project = Project.find_by(name: 'Community') - visit namespace_project_tree_path(project.namespace, project, root_ref) - end - - step 'I visit project "Internal" page' do - project = Project.find_by(name: "Internal") - visit namespace_project_path(project.namespace, project) - end - - step 'I visit project "Enterprise" page' do - project = Project.find_by(name: "Enterprise") - visit namespace_project_path(project.namespace, project) - end - - # ---------------------------------------- - # Empty Projects - # ---------------------------------------- - - step "I visit empty project page" do - project = Project.find_by(name: "Empty Public Project") - visit namespace_project_path(project.namespace, project) - end - - # ---------------------------------------- - # Public Projects - # ---------------------------------------- - - step 'I visit the public projects area' do - visit explore_projects_path - end - - step 'I visit the explore trending projects' do - visit trending_explore_projects_path - end - - step 'I visit the explore starred projects' do - visit starred_explore_projects_path - end - - step 'I visit the public groups area' do - visit explore_groups_path - end - - # ---------------------------------------- - # Snippets - # ---------------------------------------- - - step 'I visit project "Shop" snippets page' do - visit namespace_project_snippets_path(project.namespace, project) - end - - step 'I visit snippets page' do - visit snippets_path - end - - step 'I visit new snippet page' do - visit new_snippet_path - end - - def root_ref - @project.repository.root_ref - end - - def project - Project.find_by!(name: 'Shop') - end - - # ---------------------------------------- - # Errors - # ---------------------------------------- - - step 'page status code should be 404' do - status_code.should == 404 - end -end diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb deleted file mode 100644 index b60ac5e34236fa68fcf8cc5472c3abd6045aa2d6..0000000000000000000000000000000000000000 --- a/features/steps/shared/project.rb +++ /dev/null @@ -1,160 +0,0 @@ -module SharedProject - include Spinach::DSL - - # Create a project without caring about what it's called - step "I own a project" do - @project = create(:project, namespace: @user.namespace) - @project.team << [@user, :master] - end - - # Create a specific project called "Shop" - step 'I own project "Shop"' do - @project = Project.find_by(name: "Shop") - @project ||= create(:project, name: "Shop", namespace: @user.namespace, snippets_enabled: true) - @project.team << [@user, :master] - end - - # Add another user to project "Shop" - step 'I add a user to project "Shop"' do - @project = Project.find_by(name: "Shop") - other_user = create(:user, name: 'Alpha') - @project.team << [other_user, :master] - end - - # Create another specific project called "Forum" - step 'I own project "Forum"' do - @project = Project.find_by(name: "Forum") - @project ||= create(:project, name: "Forum", namespace: @user.namespace, path: 'forum_project') - @project.team << [@user, :master] - end - - # Create an empty project without caring about the name - step 'I own an empty project' do - @project = create(:empty_project, - name: 'Empty Project', namespace: @user.namespace) - @project.team << [@user, :master] - end - - step 'I visit my empty project page' do - project = Project.find_by(name: 'Empty Project') - visit namespace_project_path(project.namespace, project) - end - - step 'project "Shop" has push event' do - @project = Project.find_by(name: "Shop") - - data = { - before: Gitlab::Git::BLANK_SHA, - after: "6d394385cf567f80a8fd85055db1ab4c5295806f", - ref: "refs/heads/fix", - user_id: @user.id, - user_name: @user.name, - repository: { - name: @project.name, - url: "localhost/rubinius", - description: "", - homepage: "localhost/rubinius", - private: true - } - } - - @event = Event.create( - project: @project, - action: Event::PUSHED, - data: data, - author_id: @user.id - ) - end - - step 'I should see project "Shop" activity feed' do - project = Project.find_by(name: "Shop") - page.should have_content "#{@user.name} pushed new branch fix at #{project.name_with_namespace}" - end - - step 'I should see project settings' do - current_path.should == edit_namespace_project_path(@project.namespace, @project) - page.should have_content("Project name") - page.should have_content("Features:") - end - - def current_project - @project ||= Project.first - end - - # ---------------------------------------- - # Visibility level - # ---------------------------------------- - - step 'private project "Enterprise"' do - create :project, name: 'Enterprise' - end - - step 'I should see project "Enterprise"' do - page.should have_content "Enterprise" - end - - step 'I should not see project "Enterprise"' do - page.should_not have_content "Enterprise" - end - - step 'internal project "Internal"' do - create :project, :internal, name: 'Internal' - end - - step 'I should see project "Internal"' do - page.should have_content "Internal" - end - - step 'I should not see project "Internal"' do - page.should_not have_content "Internal" - end - - step 'public project "Community"' do - create :project, :public, name: 'Community' - end - - step 'I should see project "Community"' do - page.should have_content "Community" - end - - step 'I should not see project "Community"' do - page.should_not have_content "Community" - end - - step '"John Doe" owns private project "Enterprise"' do - user = user_exists("John Doe", username: "john_doe") - project = Project.find_by(name: "Enterprise") - project ||= create(:empty_project, name: "Enterprise", namespace: user.namespace) - project.team << [user, :master] - end - - step '"John Doe" owns internal project "Internal"' do - user = user_exists("John Doe", username: "john_doe") - project = Project.find_by(name: "Internal") - project ||= create :empty_project, :internal, name: 'Internal', namespace: user.namespace - project.team << [user, :master] - end - - step '"John Doe" owns public project "Community"' do - user = user_exists("John Doe", username: "john_doe") - project = Project.find_by(name: "Community") - project ||= create :empty_project, :public, name: 'Community', namespace: user.namespace - project.team << [user, :master] - end - - step 'public empty project "Empty Public Project"' do - create :project_empty_repo, :public, name: "Empty Public Project" - end - - step 'project "Community" has comments' do - project = Project.find_by(name: "Community") - 2.times { create(:note_on_issue, project: project) } - end - - step 'project "Shop" has labels: "bug", "feature", "enhancement"' do - project = Project.find_by(name: "Shop") - create(:label, project: project, title: 'bug') - create(:label, project: project, title: 'feature') - create(:label, project: project, title: 'enhancement') - end -end diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb deleted file mode 100644 index c5aed19331cf0e96bab9e926bfce10177d17288e..0000000000000000000000000000000000000000 --- a/features/steps/shared/project_tab.rb +++ /dev/null @@ -1,48 +0,0 @@ -require_relative 'active_tab' - -module SharedProjectTab - include Spinach::DSL - include SharedActiveTab - - step 'the active main tab should be Home' do - ensure_active_main_tab('Project') - end - - step 'the active main tab should be Files' do - ensure_active_main_tab('Files') - end - - step 'the active main tab should be Commits' do - ensure_active_main_tab('Commits') - end - - step 'the active main tab should be Network' do - ensure_active_main_tab('Network') - end - - step 'the active main tab should be Graphs' do - ensure_active_main_tab('Graphs') - end - - step 'the active main tab should be Issues' do - ensure_active_main_tab('Issues') - end - - step 'the active main tab should be Merge Requests' do - ensure_active_main_tab('Merge Requests') - end - - step 'the active main tab should be Snippets' do - ensure_active_main_tab('Snippets') - end - - step 'the active main tab should be Wiki' do - ensure_active_main_tab('Wiki') - end - - step 'the active main tab should be Settings' do - within '.nav-sidebar' do - page.should have_content('Back to project') - end - end -end diff --git a/features/steps/shared/search.rb b/features/steps/shared/search.rb deleted file mode 100644 index 6c3d601763df00236350f46cf09b9a6f53dc688b..0000000000000000000000000000000000000000 --- a/features/steps/shared/search.rb +++ /dev/null @@ -1,11 +0,0 @@ -module SharedSearch - include Spinach::DSL - - def search_snippet_contents(query) - visit "/search?search=#{URI::encode(query)}&snippets=true&scope=snippet_blobs" - end - - def search_snippet_titles(query) - visit "/search?search=#{URI::encode(query)}&snippets=true&scope=snippet_titles" - end -end diff --git a/features/steps/shared/shortcuts.rb b/features/steps/shared/shortcuts.rb deleted file mode 100644 index bbb7afec0ad33e98deed901f55175438ec31ab57..0000000000000000000000000000000000000000 --- a/features/steps/shared/shortcuts.rb +++ /dev/null @@ -1,18 +0,0 @@ -module SharedActiveTab - include Spinach::DSL - - step 'I press "g" and "p"' do - find('body').native.send_key('g') - find('body').native.send_key('p') - end - - step 'I press "g" and "i"' do - find('body').native.send_key('g') - find('body').native.send_key('i') - end - - step 'I press "g" and "m"' do - find('body').native.send_key('g') - find('body').native.send_key('m') - end -end diff --git a/features/steps/shared/snippet.rb b/features/steps/shared/snippet.rb deleted file mode 100644 index bb596c1620a2ae32a97d7aceaa5d255f3051878e..0000000000000000000000000000000000000000 --- a/features/steps/shared/snippet.rb +++ /dev/null @@ -1,63 +0,0 @@ -module SharedSnippet - include Spinach::DSL - - step 'I have public "Personal snippet one" snippet' do - create(:personal_snippet, - title: "Personal snippet one", - content: "Test content", - file_name: "snippet.rb", - visibility_level: Snippet::PUBLIC, - author: current_user) - end - - step 'I have private "Personal snippet private" snippet' do - create(:personal_snippet, - title: "Personal snippet private", - content: "Provate content", - file_name: "private_snippet.rb", - visibility_level: Snippet::PRIVATE, - author: current_user) - end - - step 'I have internal "Personal snippet internal" snippet' do - create(:personal_snippet, - title: "Personal snippet internal", - content: "Provate content", - file_name: "internal_snippet.rb", - visibility_level: Snippet::INTERNAL, - author: current_user) - end - - step 'I have a public many lined snippet' do - create(:personal_snippet, - title: 'Many lined snippet', - content: <<-END.gsub(/^\s+\|/, ''), - |line one - |line two - |line three - |line four - |line five - |line six - |line seven - |line eight - |line nine - |line ten - |line eleven - |line twelve - |line thirteen - |line fourteen - END - file_name: 'many_lined_snippet.rb', - visibility_level: Snippet::PUBLIC, - author: current_user) - end - - step 'There is public "Personal snippet one" snippet' do - create(:personal_snippet, - title: "Personal snippet one", - content: "Test content", - file_name: "snippet.rb", - visibility_level: Snippet::PUBLIC, - author: create(:user)) - end -end diff --git a/features/steps/shared/user.rb b/features/steps/shared/user.rb deleted file mode 100644 index 209d77c7acf4e50693d2389f85240a8997eac34e..0000000000000000000000000000000000000000 --- a/features/steps/shared/user.rb +++ /dev/null @@ -1,17 +0,0 @@ -module SharedUser - include Spinach::DSL - - step 'User "John Doe" exists' do - user_exists("John Doe", {username: "john_doe"}) - end - - step 'User "Mary Jane" exists' do - user_exists("Mary Jane", {username: "mary_jane"}) - end - - protected - - def user_exists(name, options = {}) - User.find_by(name: name) || create(:user, {name: name, admin: false}.merge(options)) - end -end diff --git a/features/steps/snippet_search.rb b/features/steps/snippet_search.rb deleted file mode 100644 index 669c7186c1b868901c2c4c5a69f9c6e7236f9dbc..0000000000000000000000000000000000000000 --- a/features/steps/snippet_search.rb +++ /dev/null @@ -1,56 +0,0 @@ -class Spinach::Features::SnippetSearch < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedSnippet - include SharedUser - include SharedSearch - - step 'I search for "snippet" in snippet titles' do - search_snippet_titles 'snippet' - end - - step 'I search for "snippet private" in snippet titles' do - search_snippet_titles 'snippet private' - end - - step 'I search for "line seven" in snippet contents' do - search_snippet_contents 'line seven' - end - - step 'I should see "line seven" in results' do - page.should have_content 'line seven' - end - - step 'I should see "line four" in results' do - page.should have_content 'line four' - end - - step 'I should see "line ten" in results' do - page.should have_content 'line ten' - end - - step 'I should not see "line eleven" in results' do - page.should_not have_content 'line eleven' - end - - step 'I should not see "line three" in results' do - page.should_not have_content 'line three' - end - - step 'I should see "Personal snippet one" in results' do - page.should have_content 'Personal snippet one' - end - - step 'I should see "Personal snippet private" in results' do - page.should have_content 'Personal snippet private' - end - - step 'I should not see "Personal snippet one" in results' do - page.should_not have_content 'Personal snippet one' - end - - step 'I should not see "Personal snippet private" in results' do - page.should_not have_content 'Personal snippet private' - end - -end diff --git a/features/steps/snippets/discover.rb b/features/steps/snippets/discover.rb deleted file mode 100644 index 2667c1e3d44644067d602a9acda632df17648463..0000000000000000000000000000000000000000 --- a/features/steps/snippets/discover.rb +++ /dev/null @@ -1,21 +0,0 @@ -class Spinach::Features::SnippetsDiscover < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedSnippet - - step 'I should see "Personal snippet one" in snippets' do - page.should have_content "Personal snippet one" - end - - step 'I should see "Personal snippet internal" in snippets' do - page.should have_content "Personal snippet internal" - end - - step 'I should not see "Personal snippet private" in snippets' do - page.should_not have_content "Personal snippet private" - end - - def snippet - @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") - end -end diff --git a/features/steps/snippets/public_snippets.rb b/features/steps/snippets/public_snippets.rb deleted file mode 100644 index 67669dc0a69f78a3ecfeec5035e366fa33562b1e..0000000000000000000000000000000000000000 --- a/features/steps/snippets/public_snippets.rb +++ /dev/null @@ -1,25 +0,0 @@ -class Spinach::Features::PublicSnippets < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedSnippet - - step 'I should see snippet "Personal snippet one"' do - page.should have_no_xpath("//i[@class='public-snippet']") - end - - step 'I should see raw snippet "Personal snippet one"' do - page.should have_text(snippet.content) - end - - step 'I visit snippet page "Personal snippet one"' do - visit snippet_path(snippet) - end - - step 'I visit snippet raw page "Personal snippet one"' do - visit raw_snippet_path(snippet) - end - - def snippet - @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") - end -end diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb deleted file mode 100644 index de936db85ee3141fd9a15827667cc6de07b97509..0000000000000000000000000000000000000000 --- a/features/steps/snippets/snippets.rb +++ /dev/null @@ -1,64 +0,0 @@ -class Spinach::Features::Snippets < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - include SharedSnippet - - step 'I click link "Personal snippet one"' do - click_link "Personal snippet one" - end - - step 'I should not see "Personal snippet one" in snippets' do - page.should_not have_content "Personal snippet one" - end - - step 'I click link "Edit"' do - within ".file-title" do - click_link "Edit" - end - end - - step 'I click link "Destroy"' do - click_link "remove" - end - - step 'I submit new snippet "Personal snippet three"' do - fill_in "personal_snippet_title", :with => "Personal snippet three" - fill_in "personal_snippet_file_name", :with => "my_snippet.rb" - within('.file-editor') do - find(:xpath, "//input[@id='personal_snippet_content']").set 'Content of snippet three' - end - click_button "Create snippet" - end - - step 'I should see snippet "Personal snippet three"' do - page.should have_content "Personal snippet three" - page.should have_content "Content of snippet three" - end - - step 'I submit new title "Personal snippet new title"' do - fill_in "personal_snippet_title", :with => "Personal snippet new title" - click_button "Save" - end - - step 'I should see "Personal snippet new title"' do - page.should have_content "Personal snippet new title" - end - - step 'I uncheck "Private" checkbox' do - choose "Internal" - click_button "Save" - end - - step 'I should see "Personal snippet one" public' do - page.should have_no_xpath("//i[@class='public-snippet']") - end - - step 'I visit snippet page "Personal snippet one"' do - visit snippet_path(snippet) - end - - def snippet - @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") - end -end diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb deleted file mode 100644 index 866f637ab6c8f3b7aae20207ed6aec5f1b540d71..0000000000000000000000000000000000000000 --- a/features/steps/snippets/user.rb +++ /dev/null @@ -1,55 +0,0 @@ -class Spinach::Features::SnippetsUser < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedSnippet - - step 'I visit my snippets page' do - visit user_snippets_path(current_user) - end - - step 'I should see "Personal snippet one" in snippets' do - page.should have_content "Personal snippet one" - end - - step 'I should see "Personal snippet private" in snippets' do - page.should have_content "Personal snippet private" - end - - step 'I should see "Personal snippet internal" in snippets' do - page.should have_content "Personal snippet internal" - end - - step 'I should not see "Personal snippet one" in snippets' do - page.should_not have_content "Personal snippet one" - end - - step 'I should not see "Personal snippet private" in snippets' do - page.should_not have_content "Personal snippet private" - end - - step 'I should not see "Personal snippet internal" in snippets' do - page.should_not have_content "Personal snippet internal" - end - - step 'I click "Internal" filter' do - within('.nav-stacked') do - click_link "Internal" - end - end - - step 'I click "Private" filter' do - within('.nav-stacked') do - click_link "Private" - end - end - - step 'I click "Public" filter' do - within('.nav-stacked') do - click_link "Public" - end - end - - def snippet - @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") - end -end diff --git a/features/steps/user.rb b/features/steps/user.rb deleted file mode 100644 index 10cae692a88914a1afba9a3604f6c994e7ace4e0..0000000000000000000000000000000000000000 --- a/features/steps/user.rb +++ /dev/null @@ -1,43 +0,0 @@ -class Spinach::Features::User < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedUser - include SharedProject - - step 'I should see user "John Doe" page' do - expect(title).to match(/^\s*John Doe/) - end - - step '"John Doe" has contributions' do - user = User.find_by(name: 'John Doe') - project = contributed_project - - # Issue controbution - issue_params = { title: 'Bug in old browser' } - Issues::CreateService.new(project, user, issue_params).execute - - # Push code contribution - push_params = { - project: project, - action: Event::PUSHED, - author_id: user.id, - data: { commit_count: 3 } - } - - Event.create(push_params) - end - - step 'I should see contributed projects' do - within '.contributed-projects' do - page.should have_content(@contributed_project.name) - end - end - - step 'I should see contributions calendar' do - page.should have_css('.cal-heatmap-container') - end - - def contributed_project - @contributed_project ||= create(:project, :public) - end -end diff --git a/features/support/env.rb b/features/support/env.rb deleted file mode 100644 index be17065ccfd728ddb1c1b171dd75fa901e003e0d..0000000000000000000000000000000000000000 --- a/features/support/env.rb +++ /dev/null @@ -1,54 +0,0 @@ -if ENV['SIMPLECOV'] - require 'simplecov' -end - -if ENV['COVERALLS'] - require 'coveralls' - Coveralls.wear_merged! -end - -ENV['RAILS_ENV'] = 'test' -require './config/environment' -require 'rspec' -require 'rspec/expectations' -require 'database_cleaner' -require 'spinach/capybara' -require 'sidekiq/testing/inline' - -%w(select2_helper test_env repo_helpers).each do |f| - require Rails.root.join('spec', 'support', f) -end - -Dir["#{Rails.root}/features/steps/shared/*.rb"].each {|file| require file} - -WebMock.allow_net_connect! -# -# JS driver -# -require 'capybara/poltergeist' -Capybara.javascript_driver = :poltergeist -Capybara.register_driver :poltergeist do |app| - Capybara::Poltergeist::Driver.new(app, js_errors: false, timeout: 90) -end -Spinach.hooks.on_tag("javascript") do - ::Capybara.current_driver = ::Capybara.javascript_driver -end -Capybara.default_wait_time = 60 -Capybara.ignore_hidden_elements = false - -DatabaseCleaner.strategy = :truncation - -Spinach.hooks.before_scenario do - DatabaseCleaner.start -end - -Spinach.hooks.after_scenario do - DatabaseCleaner.clean -end - -Spinach.hooks.before_run do - include RSpec::Mocks::ExampleMethods - TestEnv.init(mailer: false) - - include FactoryGirl::Syntax::Methods -end diff --git a/features/user.feature b/features/user.feature deleted file mode 100644 index 69618e929c4cee95581e22170438d837fa5ae6df..0000000000000000000000000000000000000000 --- a/features/user.feature +++ /dev/null @@ -1,78 +0,0 @@ -Feature: User - Background: - Given User "John Doe" exists - And "John Doe" owns private project "Enterprise" - - # Signed out - - Scenario: I visit user "John Doe" page while not signed in when he owns a public project - Given "John Doe" owns internal project "Internal" - And "John Doe" owns public project "Community" - When I visit user "John Doe" page - Then I should see user "John Doe" page - And I should not see project "Enterprise" - And I should not see project "Internal" - And I should see project "Community" - - Scenario: I visit user "John Doe" page while not signed in when he is not authorized to a public project - Given "John Doe" owns internal project "Internal" - When I visit user "John Doe" page - Then I should be redirected to sign in page - - # Signed in as someone else - - Scenario: I visit user "John Doe" page while signed in as someone else when he owns a public project - Given "John Doe" owns public project "Community" - And "John Doe" owns internal project "Internal" - And I sign in as a user - When I visit user "John Doe" page - Then I should see user "John Doe" page - And I should not see project "Enterprise" - And I should see project "Internal" - And I should see project "Community" - - Scenario: I visit user "John Doe" page while signed in as someone else when he is not authorized to a public project - Given "John Doe" owns internal project "Internal" - And I sign in as a user - When I visit user "John Doe" page - Then I should see user "John Doe" page - And I should not see project "Enterprise" - And I should see project "Internal" - And I should not see project "Community" - - Scenario: I visit user "John Doe" page while signed in as someone else when he is not authorized to a project I can see - Given I sign in as a user - When I visit user "John Doe" page - Then I should see user "John Doe" page - And I should not see project "Enterprise" - And I should not see project "Internal" - And I should not see project "Community" - - # Signed in as the user himself - - Scenario: I visit user "John Doe" page while signed in as "John Doe" when he has a public project - Given "John Doe" owns internal project "Internal" - And "John Doe" owns public project "Community" - And I sign in as "John Doe" - When I visit user "John Doe" page - Then I should see user "John Doe" page - And I should see project "Enterprise" - And I should see project "Internal" - And I should see project "Community" - - Scenario: I visit user "John Doe" page while signed in as "John Doe" when he has no public project - Given I sign in as "John Doe" - When I visit user "John Doe" page - Then I should see user "John Doe" page - And I should see project "Enterprise" - And I should not see project "Internal" - And I should not see project "Community" - - @javascript - Scenario: "John Doe" contribution profile - Given I sign in as a user - And "John Doe" has contributions - When I visit user "John Doe" page - Then I should see user "John Doe" page - And I should see contributed projects - And I should see contributions calendar diff --git a/lib/api/api.rb b/lib/api/api.rb deleted file mode 100644 index 60858a394079eb191bed27de86a70e8056154508..0000000000000000000000000000000000000000 --- a/lib/api/api.rb +++ /dev/null @@ -1,53 +0,0 @@ -Dir["#{Rails.root}/lib/api/*.rb"].each {|file| require file} - -module API - class API < Grape::API - include APIGuard - version 'v3', using: :path - - rescue_from ActiveRecord::RecordNotFound do - rack_response({ 'message' => '404 Not found' }.to_json, 404) - end - - rescue_from :all do |exception| - # lifted from https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb#L60 - # why is this not wrapped in something reusable? - trace = exception.backtrace - - message = "\n#{exception.class} (#{exception.message}):\n" - message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code) - message << " " << trace.join("\n ") - - API.logger.add Logger::FATAL, message - rack_response({ 'message' => '500 Internal Server Error' }, 500) - end - - format :json - content_type :txt, "text/plain" - - helpers APIHelpers - - mount Groups - mount GroupMembers - mount Users - mount Projects - mount Repositories - mount Issues - mount Milestones - mount Session - mount MergeRequests - mount Notes - mount Internal - mount SystemHooks - mount ProjectSnippets - mount ProjectMembers - mount DeployKeys - mount ProjectHooks - mount Services - mount Files - mount Commits - mount Namespaces - mount Branches - mount Labels - end -end diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb deleted file mode 100644 index b9994fcefdaba024913d585c7d319bc978022ec5..0000000000000000000000000000000000000000 --- a/lib/api/api_guard.rb +++ /dev/null @@ -1,172 +0,0 @@ -# Guard API with OAuth 2.0 Access Token - -require 'rack/oauth2' - -module APIGuard - extend ActiveSupport::Concern - - included do |base| - # OAuth2 Resource Server Authentication - use Rack::OAuth2::Server::Resource::Bearer, 'The API' do |request| - # The authenticator only fetches the raw token string - - # Must yield access token to store it in the env - request.access_token - end - - helpers HelperMethods - - install_error_responders(base) - end - - # Helper Methods for Grape Endpoint - module HelperMethods - # Invokes the doorkeeper guard. - # - # If token is presented and valid, then it sets @current_user. - # - # If the token does not have sufficient scopes to cover the requred scopes, - # then it raises InsufficientScopeError. - # - # If the token is expired, then it raises ExpiredError. - # - # If the token is revoked, then it raises RevokedError. - # - # If the token is not found (nil), then it raises TokenNotFoundError. - # - # Arguments: - # - # scopes: (optional) scopes required for this guard. - # Defaults to empty array. - # - def doorkeeper_guard!(scopes: []) - if (access_token = find_access_token).nil? - raise TokenNotFoundError - - else - case validate_access_token(access_token, scopes) - when Oauth2::AccessTokenValidationService::INSUFFICIENT_SCOPE - raise InsufficientScopeError.new(scopes) - when Oauth2::AccessTokenValidationService::EXPIRED - raise ExpiredError - when Oauth2::AccessTokenValidationService::REVOKED - raise RevokedError - when Oauth2::AccessTokenValidationService::VALID - @current_user = User.find(access_token.resource_owner_id) - end - end - end - - def doorkeeper_guard(scopes: []) - if access_token = find_access_token - case validate_access_token(access_token, scopes) - when Oauth2::AccessTokenValidationService::INSUFFICIENT_SCOPE - raise InsufficientScopeError.new(scopes) - - when Oauth2::AccessTokenValidationService::EXPIRED - raise ExpiredError - - when Oauth2::AccessTokenValidationService::REVOKED - raise RevokedError - - when Oauth2::AccessTokenValidationService::VALID - @current_user = User.find(access_token.resource_owner_id) - end - end - end - - def current_user - @current_user - end - - private - def find_access_token - @access_token ||= Doorkeeper.authenticate(doorkeeper_request, Doorkeeper.configuration.access_token_methods) - end - - def doorkeeper_request - @doorkeeper_request ||= ActionDispatch::Request.new(env) - end - - def validate_access_token(access_token, scopes) - Oauth2::AccessTokenValidationService.validate(access_token, scopes: scopes) - end - end - - module ClassMethods - # Installs the doorkeeper guard on the whole Grape API endpoint. - # - # Arguments: - # - # scopes: (optional) scopes required for this guard. - # Defaults to empty array. - # - def guard_all!(scopes: []) - before do - guard! scopes: scopes - end - end - - private - def install_error_responders(base) - error_classes = [ MissingTokenError, TokenNotFoundError, - ExpiredError, RevokedError, InsufficientScopeError] - - base.send :rescue_from, *error_classes, oauth2_bearer_token_error_handler - end - - def oauth2_bearer_token_error_handler - Proc.new do |e| - response = - case e - when MissingTokenError - Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new - - when TokenNotFoundError - Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( - :invalid_token, - "Bad Access Token.") - - when ExpiredError - Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( - :invalid_token, - "Token is expired. You can either do re-authorization or token refresh.") - - when RevokedError - Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new( - :invalid_token, - "Token was revoked. You have to re-authorize from the user.") - - when InsufficientScopeError - # FIXME: ForbiddenError (inherited from Bearer::Forbidden of Rack::Oauth2) - # does not include WWW-Authenticate header, which breaks the standard. - Rack::OAuth2::Server::Resource::Bearer::Forbidden.new( - :insufficient_scope, - Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION[:insufficient_scope], - { scope: e.scopes }) - end - - response.finish - end - end - end - - # - # Exceptions - # - - class MissingTokenError < StandardError; end - - class TokenNotFoundError < StandardError; end - - class ExpiredError < StandardError; end - - class RevokedError < StandardError; end - - class InsufficientScopeError < StandardError - attr_reader :scopes - def initialize(scopes) - @scopes = scopes - end - end -end diff --git a/lib/api/branches.rb b/lib/api/branches.rb deleted file mode 100644 index 592100a7045b37e84072190392478d499335ee1b..0000000000000000000000000000000000000000 --- a/lib/api/branches.rb +++ /dev/null @@ -1,119 +0,0 @@ -require 'mime/types' - -module API - # Projects API - class Branches < Grape::API - before { authenticate! } - before { authorize! :download_code, user_project } - - resource :projects do - # Get a project repository branches - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/repository/branches - get ":id/repository/branches" do - branches = user_project.repository.branches.sort_by(&:name) - present branches, with: Entities::RepoObject, project: user_project - end - - # Get a single branch - # - # Parameters: - # id (required) - The ID of a project - # branch (required) - The name of the branch - # Example Request: - # GET /projects/:id/repository/branches/:branch - get ':id/repository/branches/:branch', requirements: { branch: /.*/ } do - @branch = user_project.repository.branches.find { |item| item.name == params[:branch] } - not_found!("Branch") unless @branch - present @branch, with: Entities::RepoObject, project: user_project - end - - # Protect a single branch - # - # Parameters: - # id (required) - The ID of a project - # branch (required) - The name of the branch - # Example Request: - # PUT /projects/:id/repository/branches/:branch/protect - put ':id/repository/branches/:branch/protect', - requirements: { branch: /.*/ } do - - authorize_admin_project - - @branch = user_project.repository.find_branch(params[:branch]) - not_found!("Branch") unless @branch - protected_branch = user_project.protected_branches.find_by(name: @branch.name) - user_project.protected_branches.create(name: @branch.name) unless protected_branch - - present @branch, with: Entities::RepoObject, project: user_project - end - - # Unprotect a single branch - # - # Parameters: - # id (required) - The ID of a project - # branch (required) - The name of the branch - # Example Request: - # PUT /projects/:id/repository/branches/:branch/unprotect - put ':id/repository/branches/:branch/unprotect', - requirements: { branch: /.*/ } do - - authorize_admin_project - - @branch = user_project.repository.find_branch(params[:branch]) - not_found!("Branch does not exist") unless @branch - protected_branch = user_project.protected_branches.find_by(name: @branch.name) - protected_branch.destroy if protected_branch - - present @branch, with: Entities::RepoObject, project: user_project - end - - # Create branch - # - # Parameters: - # id (required) - The ID of a project - # branch_name (required) - The name of the branch - # ref (required) - Create branch from commit sha or existing branch - # Example Request: - # POST /projects/:id/repository/branches - post ":id/repository/branches" do - authorize_push_project - result = CreateBranchService.new(user_project, current_user). - execute(params[:branch_name], params[:ref]) - - if result[:status] == :success - present result[:branch], - with: Entities::RepoObject, - project: user_project - else - render_api_error!(result[:message], 400) - end - end - - # Delete branch - # - # Parameters: - # id (required) - The ID of a project - # branch (required) - The name of the branch - # Example Request: - # DELETE /projects/:id/repository/branches/:branch - delete ":id/repository/branches/:branch", - requirements: { branch: /.*/ } do - authorize_push_project - result = DeleteBranchService.new(user_project, current_user). - execute(params[:branch]) - - if result[:status] == :success - { - branch_name: params[:branch] - } - else - render_api_error!(result[:message], result[:return_code]) - end - end - end - end -end diff --git a/lib/api/commits.rb b/lib/api/commits.rb deleted file mode 100644 index 0de4e720ffe00ca8c8af9b0746e234b7d0ac3902..0000000000000000000000000000000000000000 --- a/lib/api/commits.rb +++ /dev/null @@ -1,116 +0,0 @@ -require 'mime/types' - -module API - # Projects commits API - class Commits < Grape::API - before { authenticate! } - before { authorize! :download_code, user_project } - - resource :projects do - # Get a project repository commits - # - # Parameters: - # id (required) - The ID of a project - # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used - # Example Request: - # GET /projects/:id/repository/commits - get ":id/repository/commits" do - page = (params[:page] || 0).to_i - per_page = (params[:per_page] || 20).to_i - ref = params[:ref_name] || user_project.try(:default_branch) || 'master' - - commits = user_project.repository.commits(ref, nil, per_page, page * per_page) - present commits, with: Entities::RepoCommit - end - - # Get a specific commit of a project - # - # Parameters: - # id (required) - The ID of a project - # sha (required) - The commit hash or name of a repository branch or tag - # Example Request: - # GET /projects/:id/repository/commits/:sha - get ":id/repository/commits/:sha" do - sha = params[:sha] - commit = user_project.repository.commit(sha) - not_found! "Commit" unless commit - present commit, with: Entities::RepoCommitDetail - end - - # Get the diff for a specific commit of a project - # - # Parameters: - # id (required) - The ID of a project - # sha (required) - The commit or branch name - # Example Request: - # GET /projects/:id/repository/commits/:sha/diff - get ":id/repository/commits/:sha/diff" do - sha = params[:sha] - commit = user_project.repository.commit(sha) - not_found! "Commit" unless commit - commit.diffs - end - - # Get a commit's comments - # - # Parameters: - # id (required) - The ID of a project - # sha (required) - The commit hash - # Examples: - # GET /projects/:id/repository/commits/:sha/comments - get ':id/repository/commits/:sha/comments' do - sha = params[:sha] - commit = user_project.repository.commit(sha) - not_found! 'Commit' unless commit - notes = Note.where(commit_id: commit.id) - present paginate(notes), with: Entities::CommitNote - end - - # Post comment to commit - # - # Parameters: - # id (required) - The ID of a project - # sha (required) - The commit hash - # note (required) - Text of comment - # path (optional) - The file path - # line (optional) - The line number - # line_type (optional) - The type of line (new or old) - # Examples: - # POST /projects/:id/repository/commits/:sha/comments - post ':id/repository/commits/:sha/comments' do - required_attributes! [:note] - - sha = params[:sha] - commit = user_project.repository.commit(sha) - not_found! 'Commit' unless commit - opts = { - note: params[:note], - noteable_type: 'Commit', - commit_id: commit.id - } - - if params[:path] && params[:line] && params[:line_type] - commit.diffs.each do |diff| - next unless diff.new_path == params[:path] - lines = Gitlab::Diff::Parser.new.parse(diff.diff.lines.to_a) - - lines.each do |line| - next unless line.new_pos == params[:line].to_i && line.type == params[:line_type] - break opts[:line_code] = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos) - end - - break if opts[:line_code] - end - end - - note = ::Notes::CreateService.new(user_project, current_user, opts).execute - - if note.save - present note, with: Entities::CommitNote - else - render_api_error!("Failed to save note #{note.errors.messages}", 400) - end - end - end - end -end diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb deleted file mode 100644 index 06eb7756841fe4ef5540bfef81480cb6fd2ddda5..0000000000000000000000000000000000000000 --- a/lib/api/deploy_keys.rb +++ /dev/null @@ -1,75 +0,0 @@ -module API - # Projects API - class DeployKeys < Grape::API - before { authenticate! } - before { authorize_admin_project } - - resource :projects do - # Get a specific project's keys - # - # Example Request: - # GET /projects/:id/keys - get ":id/keys" do - present user_project.deploy_keys, with: Entities::SSHKey - end - - # Get single key owned by currently authenticated user - # - # Example Request: - # GET /projects/:id/keys/:id - get ":id/keys/:key_id" do - key = user_project.deploy_keys.find params[:key_id] - present key, with: Entities::SSHKey - end - - # Add new ssh key to currently authenticated user - # If deploy key already exists - it will be joined to project - # but only if original one was is accessible by same user - # - # Parameters: - # key (required) - New SSH Key - # title (required) - New SSH Key's title - # Example Request: - # POST /projects/:id/keys - post ":id/keys" do - attrs = attributes_for_keys [:title, :key] - - if attrs[:key].present? - attrs[:key].strip! - - # check if key already exist in project - key = user_project.deploy_keys.find_by(key: attrs[:key]) - if key - present key, with: Entities::SSHKey - return - end - - # Check for available deploy keys in other projects - key = current_user.accessible_deploy_keys.find_by(key: attrs[:key]) - if key - user_project.deploy_keys << key - present key, with: Entities::SSHKey - return - end - end - - key = DeployKey.new attrs - - if key.valid? && user_project.deploy_keys << key - present key, with: Entities::SSHKey - else - render_validation_error!(key) - end - end - - # Delete existed ssh key of currently authenticated user - # - # Example Request: - # DELETE /projects/:id/keys/:id - delete ":id/keys/:key_id" do - key = user_project.deploy_keys.find params[:key_id] - key.destroy - end - end - end -end diff --git a/lib/api/entities.rb b/lib/api/entities.rb deleted file mode 100644 index 36332bc6514b220e99ae32ef67b9b7063a12fea4..0000000000000000000000000000000000000000 --- a/lib/api/entities.rb +++ /dev/null @@ -1,280 +0,0 @@ -module API - module Entities - class UserSafe < Grape::Entity - expose :name, :username - end - - class UserBasic < UserSafe - expose :id, :state, :avatar_url - end - - class User < UserBasic - expose :created_at - expose :is_admin?, as: :is_admin - expose :bio, :skype, :linkedin, :twitter, :website_url - end - - class Identity < Grape::Entity - expose :provider, :extern_uid - end - - class UserFull < User - expose :email - expose :theme_id, :color_scheme_id, :projects_limit - expose :identities, using: Entities::Identity - expose :can_create_group?, as: :can_create_group - expose :can_create_project?, as: :can_create_project - end - - class UserLogin < UserFull - expose :private_token - end - - class Hook < Grape::Entity - expose :id, :url, :created_at - end - - class ProjectHook < Hook - expose :project_id, :push_events - expose :issues_events, :merge_requests_events, :tag_push_events - end - - class ForkedFromProject < Grape::Entity - expose :id - expose :name, :name_with_namespace - expose :path, :path_with_namespace - end - - class Project < Grape::Entity - expose :id, :description, :default_branch, :tag_list - expose :public?, as: :public - expose :archived?, as: :archived - expose :visibility_level, :ssh_url_to_repo, :http_url_to_repo, :web_url - expose :owner, using: Entities::UserBasic, unless: ->(project, options) { project.group } - expose :name, :name_with_namespace - expose :path, :path_with_namespace - expose :issues_enabled, :merge_requests_enabled, :wiki_enabled, :snippets_enabled, :created_at, :last_activity_at - expose :creator_id - expose :namespace - expose :forked_from_project, using: Entities::ForkedFromProject, if: lambda{ | project, options | project.forked? } - expose :avatar_url - end - - class ProjectMember < UserBasic - expose :access_level do |user, options| - options[:project].project_members.find_by(user_id: user.id).access_level - end - end - - class Group < Grape::Entity - expose :id, :name, :path, :description - end - - class GroupDetail < Group - expose :projects, using: Entities::Project - end - - class GroupMember < UserBasic - expose :access_level do |user, options| - options[:group].group_members.find_by(user_id: user.id).access_level - end - end - - class RepoTag < Grape::Entity - expose :name - expose :message do |repo_obj, _options| - if repo_obj.respond_to?(:message) - repo_obj.message - else - nil - end - end - - expose :commit do |repo_obj, options| - if repo_obj.respond_to?(:commit) - repo_obj.commit - elsif options[:project] - options[:project].repository.commit(repo_obj.target) - end - end - end - - class RepoObject < Grape::Entity - expose :name - - expose :commit do |repo_obj, options| - if repo_obj.respond_to?(:commit) - repo_obj.commit - elsif options[:project] - options[:project].repository.commit(repo_obj.target) - end - end - - expose :protected do |repo, options| - if options[:project] - options[:project].protected_branch? repo.name - end - end - end - - class RepoTreeObject < Grape::Entity - expose :id, :name, :type - - expose :mode do |obj, options| - filemode = obj.mode.to_s(8) - filemode = "0" + filemode if filemode.length < 6 - filemode - end - end - - class RepoCommit < Grape::Entity - expose :id, :short_id, :title, :author_name, :author_email, :created_at - expose :safe_message, as: :message - end - - class RepoCommitDetail < RepoCommit - expose :parent_ids, :committed_date, :authored_date - end - - class ProjectSnippet < Grape::Entity - expose :id, :title, :file_name - expose :author, using: Entities::UserBasic - expose :expires_at, :updated_at, :created_at - end - - class ProjectEntity < Grape::Entity - expose :id, :iid - expose(:project_id) { |entity| entity.project.id } - expose :title, :description - expose :state, :created_at, :updated_at - end - - class RepoDiff < Grape::Entity - expose :old_path, :new_path, :a_mode, :b_mode, :diff - expose :new_file, :renamed_file, :deleted_file - end - - class Milestone < ProjectEntity - expose :due_date - end - - class Issue < ProjectEntity - expose :label_names, as: :labels - expose :milestone, using: Entities::Milestone - expose :assignee, :author, using: Entities::UserBasic - end - - class MergeRequest < ProjectEntity - expose :target_branch, :source_branch, :upvotes, :downvotes - expose :author, :assignee, using: Entities::UserBasic - expose :source_project_id, :target_project_id - expose :label_names, as: :labels - expose :description - expose :milestone, using: Entities::Milestone - end - - class MergeRequestChanges < MergeRequest - expose :diffs, as: :changes, using: Entities::RepoDiff do |compare, _| - compare.diffs - end - end - - class SSHKey < Grape::Entity - expose :id, :title, :key, :created_at - end - - class Note < Grape::Entity - expose :id - expose :note, as: :body - expose :attachment_identifier, as: :attachment - expose :author, using: Entities::UserBasic - expose :created_at - end - - class MRNote < Grape::Entity - expose :note - expose :author, using: Entities::UserBasic - end - - class CommitNote < Grape::Entity - expose :note - expose(:path) { |note| note.diff_file_name } - expose(:line) { |note| note.diff_new_line } - expose(:line_type) { |note| note.diff_line_type } - expose :author, using: Entities::UserBasic - end - - class Event < Grape::Entity - expose :title, :project_id, :action_name - expose :target_id, :target_type, :author_id - expose :data, :target_title - expose :created_at - - expose :author_username do |event, options| - if event.author - event.author.username - end - end - end - - class Namespace < Grape::Entity - expose :id, :path, :kind - end - - class ProjectAccess < Grape::Entity - expose :access_level - expose :notification_level - end - - class GroupAccess < Grape::Entity - expose :access_level - expose :notification_level - end - - class ProjectWithAccess < Project - expose :permissions do - expose :project_access, using: Entities::ProjectAccess do |project, options| - project.project_members.find_by(user_id: options[:user].id) - end - - expose :group_access, using: Entities::GroupAccess do |project, options| - if project.group - project.group.group_members.find_by(user_id: options[:user].id) - end - end - end - end - - class Label < Grape::Entity - expose :name, :color - end - - class Compare < Grape::Entity - expose :commit, using: Entities::RepoCommit do |compare, options| - Commit.decorate(compare.commits).last - end - - expose :commits, using: Entities::RepoCommit do |compare, options| - Commit.decorate(compare.commits) - end - - expose :diffs, using: Entities::RepoDiff do |compare, options| - compare.diffs - end - - expose :compare_timeout do |compare, options| - compare.timeout - end - - expose :same, as: :compare_same_ref - end - - class Contributor < Grape::Entity - expose :name, :email, :commits, :additions, :deletions - end - - class BroadcastMessage < Grape::Entity - expose :message, :starts_at, :ends_at, :color, :font - end - end -end diff --git a/lib/api/files.rb b/lib/api/files.rb deleted file mode 100644 index 3176ef0e256297e489176aea1a6d92123cbcb60a..0000000000000000000000000000000000000000 --- a/lib/api/files.rb +++ /dev/null @@ -1,158 +0,0 @@ -module API - # Projects API - class Files < Grape::API - before { authenticate! } - - resource :projects do - # Get file from repository - # File content is Base64 encoded - # - # Parameters: - # file_path (required) - The path to the file. Ex. lib/class.rb - # ref (required) - The name of branch, tag or commit - # - # Example Request: - # GET /projects/:id/repository/files - # - # Example response: - # { - # "file_name": "key.rb", - # "file_path": "app/models/key.rb", - # "size": 1476, - # "encoding": "base64", - # "content": "IyA9PSBTY2hlbWEgSW5mb3...", - # "ref": "master", - # "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83", - # "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50" - # } - # - get ":id/repository/files" do - authorize! :download_code, user_project - - required_attributes! [:file_path, :ref] - attrs = attributes_for_keys [:file_path, :ref] - ref = attrs.delete(:ref) - file_path = attrs.delete(:file_path) - - commit = user_project.repository.commit(ref) - not_found! 'Commit' unless commit - - blob = user_project.repository.blob_at(commit.sha, file_path) - - if blob - status(200) - - { - file_name: blob.name, - file_path: blob.path, - size: blob.size, - encoding: "base64", - content: Base64.encode64(blob.data), - ref: ref, - blob_id: blob.id, - commit_id: commit.id, - } - else - not_found! 'File' - end - end - - # Create new file in repository - # - # Parameters: - # file_path (required) - The path to new file. Ex. lib/class.rb - # branch_name (required) - The name of branch - # content (required) - File content - # commit_message (required) - Commit message - # - # Example Request: - # POST /projects/:id/repository/files - # - post ":id/repository/files" do - authorize! :push_code, user_project - - required_attributes! [:file_path, :branch_name, :content, :commit_message] - attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message, :encoding] - branch_name = attrs.delete(:branch_name) - file_path = attrs.delete(:file_path) - result = ::Files::CreateService.new(user_project, current_user, attrs, branch_name, file_path).execute - - if result[:status] == :success - status(201) - - { - file_path: file_path, - branch_name: branch_name - } - else - render_api_error!(result[:message], 400) - end - end - - # Update existing file in repository - # - # Parameters: - # file_path (optional) - The path to file. Ex. lib/class.rb - # branch_name (required) - The name of branch - # content (required) - File content - # commit_message (required) - Commit message - # - # Example Request: - # PUT /projects/:id/repository/files - # - put ":id/repository/files" do - authorize! :push_code, user_project - - required_attributes! [:file_path, :branch_name, :content, :commit_message] - attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message, :encoding] - branch_name = attrs.delete(:branch_name) - file_path = attrs.delete(:file_path) - result = ::Files::UpdateService.new(user_project, current_user, attrs, branch_name, file_path).execute - - if result[:status] == :success - status(200) - - { - file_path: file_path, - branch_name: branch_name - } - else - http_status = result[:http_status] || 400 - render_api_error!(result[:message], http_status) - end - end - - # Delete existing file in repository - # - # Parameters: - # file_path (optional) - The path to file. Ex. lib/class.rb - # branch_name (required) - The name of branch - # content (required) - File content - # commit_message (required) - Commit message - # - # Example Request: - # DELETE /projects/:id/repository/files - # - delete ":id/repository/files" do - authorize! :push_code, user_project - - required_attributes! [:file_path, :branch_name, :commit_message] - attrs = attributes_for_keys [:file_path, :branch_name, :commit_message] - branch_name = attrs.delete(:branch_name) - file_path = attrs.delete(:file_path) - result = ::Files::DeleteService.new(user_project, current_user, attrs, branch_name, file_path).execute - - if result[:status] == :success - status(200) - - { - file_path: file_path, - branch_name: branch_name - } - else - render_api_error!(result[:message], 400) - end - end - end - end -end diff --git a/lib/api/group_members.rb b/lib/api/group_members.rb deleted file mode 100644 index ab9b7c602b5dc728f206b05a2f8edac8face4b50..0000000000000000000000000000000000000000 --- a/lib/api/group_members.rb +++ /dev/null @@ -1,87 +0,0 @@ -module API - class GroupMembers < Grape::API - before { authenticate! } - - resource :groups do - # Get a list of group members viewable by the authenticated user. - # - # Example Request: - # GET /groups/:id/members - get ":id/members" do - group = find_group(params[:id]) - users = group.users - present users, with: Entities::GroupMember, group: group - end - - # Add a user to the list of group members - # - # Parameters: - # id (required) - group id - # user_id (required) - the users id - # access_level (required) - Project access level - # Example Request: - # POST /groups/:id/members - post ":id/members" do - group = find_group(params[:id]) - authorize! :admin_group, group - required_attributes! [:user_id, :access_level] - - unless validate_access_level?(params[:access_level]) - render_api_error!("Wrong access level", 422) - end - - if group.group_members.find_by(user_id: params[:user_id]) - render_api_error!("Already exists", 409) - end - - group.add_users([params[:user_id]], params[:access_level], current_user) - member = group.group_members.find_by(user_id: params[:user_id]) - present member.user, with: Entities::GroupMember, group: group - end - - # Update group member - # - # Parameters: - # id (required) - The ID of a group - # user_id (required) - The ID of a group member - # access_level (required) - Project access level - # Example Request: - # PUT /groups/:id/members/:user_id - put ':id/members/:user_id' do - group = find_group(params[:id]) - authorize! :admin_group, group - required_attributes! [:access_level] - - group_member = group.group_members.find_by(user_id: params[:user_id]) - not_found!('User can not be found') if group_member.nil? - - if group_member.update_attributes(access_level: params[:access_level]) - @member = group_member.user - present @member, with: Entities::GroupMember, group: group - else - handle_member_errors group_member.errors - end - end - - # Remove member. - # - # Parameters: - # id (required) - group id - # user_id (required) - the users id - # - # Example Request: - # DELETE /groups/:id/members/:user_id - delete ":id/members/:user_id" do - group = find_group(params[:id]) - authorize! :admin_group, group - member = group.group_members.find_by(user_id: params[:user_id]) - - if member.nil? - render_api_error!("404 Not Found - user_id:#{params[:user_id]} not a member of group #{group.name}",404) - else - member.destroy - end - end - end - end -end diff --git a/lib/api/groups.rb b/lib/api/groups.rb deleted file mode 100644 index 8cb9f920975d953e50951063e080e9671d19243a..0000000000000000000000000000000000000000 --- a/lib/api/groups.rb +++ /dev/null @@ -1,89 +0,0 @@ -module API - # groups API - class Groups < Grape::API - before { authenticate! } - - resource :groups do - # Get a groups list - # - # Example Request: - # GET /groups - get do - @groups = if current_user.admin - Group.all - else - current_user.groups - end - - @groups = @groups.search(params[:search]) if params[:search].present? - @groups = paginate @groups - present @groups, with: Entities::Group - end - - # Create group. Available only for admin - # - # Parameters: - # name (required) - The name of the group - # path (required) - The path of the group - # Example Request: - # POST /groups - post do - authenticated_as_admin! - required_attributes! [:name, :path] - - attrs = attributes_for_keys [:name, :path, :description] - @group = Group.new(attrs) - - if @group.save - @group.add_owner(current_user) - present @group, with: Entities::Group - else - render_api_error!("Failed to save group #{@group.errors.messages}", 400) - end - end - - # Get a single group, with containing projects - # - # Parameters: - # id (required) - The ID of a group - # Example Request: - # GET /groups/:id - get ":id" do - group = find_group(params[:id]) - present group, with: Entities::GroupDetail - end - - # Remove group - # - # Parameters: - # id (required) - The ID of a group - # Example Request: - # DELETE /groups/:id - delete ":id" do - group = find_group(params[:id]) - authorize! :admin_group, group - group.destroy - end - - # Transfer a project to the Group namespace - # - # Parameters: - # id - group id - # project_id - project id - # Example Request: - # POST /groups/:id/projects/:project_id - post ":id/projects/:project_id" do - authenticated_as_admin! - group = Group.find(params[:id]) - project = Project.find(params[:project_id]) - result = ::Projects::TransferService.new(project, current_user, namespace_id: group.id).execute - - if result - present group - else - render_api_error!("Failed to transfer project #{project.errors.messages}", 400) - end - end - end - end -end diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb deleted file mode 100644 index be133a2920bfaa0105b444b7f1c16391bd530d2f..0000000000000000000000000000000000000000 --- a/lib/api/helpers.rb +++ /dev/null @@ -1,250 +0,0 @@ -module API - module APIHelpers - PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN" - PRIVATE_TOKEN_PARAM = :private_token - SUDO_HEADER ="HTTP_SUDO" - SUDO_PARAM = :sudo - - def parse_boolean(value) - [ true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON' ].include?(value) - end - - def current_user - private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s - @current_user ||= (User.find_by(authentication_token: private_token) || doorkeeper_guard) - - unless @current_user && Gitlab::UserAccess.allowed?(@current_user) - return nil - end - - identifier = sudo_identifier() - - # If the sudo is the current user do nothing - if identifier && !(@current_user.id == identifier || @current_user.username == identifier) - render_api_error!('403 Forbidden: Must be admin to use sudo', 403) unless @current_user.is_admin? - @current_user = User.by_username_or_id(identifier) - not_found!("No user id or username for: #{identifier}") if @current_user.nil? - end - - @current_user - end - - def sudo_identifier() - identifier ||= params[SUDO_PARAM] ||= env[SUDO_HEADER] - - # Regex for integers - if !!(identifier =~ /^[0-9]+$/) - identifier.to_i - else - identifier - end - end - - def user_project - @project ||= find_project(params[:id]) - @project || not_found!("Project") - end - - def find_project(id) - project = Project.find_with_namespace(id) || Project.find_by(id: id) - - if project && can?(current_user, :read_project, project) - project - else - nil - end - end - - def find_group(id) - begin - group = Group.find(id) - rescue ActiveRecord::RecordNotFound - group = Group.find_by!(path: id) - end - - if can?(current_user, :read_group, group) - group - else - forbidden!("#{current_user.username} lacks sufficient "\ - "access to #{group.name}") - end - end - - def paginate(relation) - per_page = params[:per_page].to_i - paginated = relation.page(params[:page]).per(per_page) - add_pagination_headers(paginated, per_page) - - paginated - end - - def authenticate! - unauthorized! unless current_user - end - - def authenticate_by_gitlab_shell_token! - input = params['secret_token'].try(:chomp) - unless Devise.secure_compare(secret_token, input) - unauthorized! - end - end - - def authenticated_as_admin! - forbidden! unless current_user.is_admin? - end - - def authorize!(action, subject) - unless abilities.allowed?(current_user, action, subject) - forbidden! - end - end - - def authorize_push_project - authorize! :push_code, user_project - end - - def authorize_admin_project - authorize! :admin_project, user_project - end - - def can?(object, action, subject) - abilities.allowed?(object, action, subject) - end - - # Checks the occurrences of required attributes, each attribute must be present in the params hash - # or a Bad Request error is invoked. - # - # Parameters: - # keys (required) - A hash consisting of keys that must be present - def required_attributes!(keys) - keys.each do |key| - bad_request!(key) unless params[key].present? - end - end - - def attributes_for_keys(keys) - attrs = {} - - keys.each do |key| - if params[key].present? or (params.has_key?(key) and params[key] == false) - attrs[key] = params[key] - end - end - - ActionController::Parameters.new(attrs).permit! - end - - # Helper method for validating all labels against its names - def validate_label_params(params) - errors = {} - - if params[:labels].present? - params[:labels].split(',').each do |label_name| - label = user_project.labels.create_with( - color: Label::DEFAULT_COLOR).find_or_initialize_by( - title: label_name.strip) - - if label.invalid? - errors[label.title] = label.errors - end - end - end - - errors - end - - def validate_access_level?(level) - Gitlab::Access.options_with_owner.values.include? level.to_i - end - - def issuable_order_by - if params["order_by"] == 'updated_at' - 'updated_at' - else - 'created_at' - end - end - - def issuable_sort - if params["sort"] == 'asc' - :asc - else - :desc - end - end - - # error helpers - - def forbidden!(reason = nil) - message = ['403 Forbidden'] - message << " - #{reason}" if reason - render_api_error!(message.join(' '), 403) - end - - def bad_request!(attribute) - message = ["400 (Bad request)"] - message << "\"" + attribute.to_s + "\" not given" - render_api_error!(message.join(' '), 400) - end - - def not_found!(resource = nil) - message = ["404"] - message << resource if resource - message << "Not Found" - render_api_error!(message.join(' '), 404) - end - - def unauthorized! - render_api_error!('401 Unauthorized', 401) - end - - def not_allowed! - render_api_error!('405 Method Not Allowed', 405) - end - - def conflict!(message = nil) - render_api_error!(message || '409 Conflict', 409) - end - - def render_validation_error!(model) - if model.errors.any? - render_api_error!(model.errors.messages || '400 Bad Request', 400) - end - end - - def render_api_error!(message, status) - error!({ 'message' => message }, status) - end - - private - - def add_pagination_headers(paginated, per_page) - request_url = request.url.split('?').first - - links = [] - links << %(<#{request_url}?page=#{paginated.current_page - 1}&per_page=#{per_page}>; rel="prev") unless paginated.first_page? - links << %(<#{request_url}?page=#{paginated.current_page + 1}&per_page=#{per_page}>; rel="next") unless paginated.last_page? - links << %(<#{request_url}?page=1&per_page=#{per_page}>; rel="first") - links << %(<#{request_url}?page=#{paginated.total_pages}&per_page=#{per_page}>; rel="last") - - header 'Link', links.join(', ') - end - - def abilities - @abilities ||= begin - abilities = Six.new - abilities << Ability - abilities - end - end - - def secret_token - File.read(Rails.root.join('.gitlab_shell_secret')).chomp - end - - def handle_member_errors(errors) - error!(errors[:access_level], 422) if errors[:access_level].any? - not_found!(errors) - end - end -end diff --git a/lib/api/internal.rb b/lib/api/internal.rb deleted file mode 100644 index f98a17773e7e24d046d8e4780081529c8d4acb58..0000000000000000000000000000000000000000 --- a/lib/api/internal.rb +++ /dev/null @@ -1,85 +0,0 @@ -module API - # Internal access API - class Internal < Grape::API - before { authenticate_by_gitlab_shell_token! } - - namespace 'internal' do - # Check if git command is allowed to project - # - # Params: - # key_id - ssh key id for Git over SSH - # user_id - user id for Git over HTTP - # project - project path with namespace - # action - git action (git-upload-pack or git-receive-pack) - # ref - branch name - # forced_push - forced_push - # - post "/allowed" do - status 200 - - actor = - if params[:key_id] - Key.find_by(id: params[:key_id]) - elsif params[:user_id] - User.find_by(id: params[:user_id]) - end - - unless actor - return Gitlab::GitAccessStatus.new(false, 'No such user or key') - end - - project_path = params[:project] - - # Check for *.wiki repositories. - # Strip out the .wiki from the pathname before finding the - # project. This applies the correct project permissions to - # the wiki repository as well. - wiki = project_path.end_with?('.wiki') - project_path.chomp!('.wiki') if wiki - - project = Project.find_with_namespace(project_path) - - if project - access = - if wiki - Gitlab::GitAccessWiki.new(actor, project) - else - Gitlab::GitAccess.new(actor, project) - end - - status = access.check(params[:action], params[:changes]) - end - - if project && access.can_read_project? - status - else - Gitlab::GitAccessStatus.new(false, 'No such project') - end - end - - # - # Discover user by ssh key - # - get "/discover" do - key = Key.find(params[:key_id]) - present key.user, with: Entities::UserSafe - end - - get "/check" do - { - api_version: API.version, - gitlab_version: Gitlab::VERSION, - gitlab_rev: Gitlab::REVISION, - } - end - - get "/broadcast_message" do - if message = BroadcastMessage.current - present message, with: Entities::BroadcastMessage - else - {} - end - end - end - end -end diff --git a/lib/api/issues.rb b/lib/api/issues.rb deleted file mode 100644 index ff062be60404976a99eeeabd2e997e845188e22e..0000000000000000000000000000000000000000 --- a/lib/api/issues.rb +++ /dev/null @@ -1,181 +0,0 @@ -module API - # Issues API - class Issues < Grape::API - before { authenticate! } - - helpers do - def filter_issues_state(issues, state) - case state - when 'opened' then issues.opened - when 'closed' then issues.closed - else issues - end - end - - def filter_issues_labels(issues, labels) - issues.includes(:labels).where('labels.title' => labels.split(',')) - end - - def filter_issues_milestone(issues, milestone) - issues.includes(:milestone).where('milestones.title' => milestone) - end - end - - resource :issues do - # Get currently authenticated user's issues - # - # Parameters: - # state (optional) - Return "opened" or "closed" issues - # labels (optional) - Comma-separated list of label names - # order_by (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` - # sort (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` - # - # Example Requests: - # GET /issues - # GET /issues?state=opened - # GET /issues?state=closed - # GET /issues?labels=foo - # GET /issues?labels=foo,bar - # GET /issues?labels=foo,bar&state=opened - get do - issues = current_user.issues - issues = filter_issues_state(issues, params[:state]) unless params[:state].nil? - issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil? - issues.reorder(issuable_order_by => issuable_sort) - present paginate(issues), with: Entities::Issue - end - end - - resource :projects do - # Get a list of project issues - # - # Parameters: - # id (required) - The ID of a project - # state (optional) - Return "opened" or "closed" issues - # labels (optional) - Comma-separated list of label names - # milestone (optional) - Milestone title - # order_by (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` - # sort (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` - # - # Example Requests: - # GET /projects/:id/issues - # GET /projects/:id/issues?state=opened - # GET /projects/:id/issues?state=closed - # GET /projects/:id/issues?labels=foo - # GET /projects/:id/issues?labels=foo,bar - # GET /projects/:id/issues?labels=foo,bar&state=opened - # GET /projects/:id/issues?milestone=1.0.0 - # GET /projects/:id/issues?milestone=1.0.0&state=closed - get ":id/issues" do - issues = user_project.issues - issues = filter_issues_state(issues, params[:state]) unless params[:state].nil? - issues = filter_issues_labels(issues, params[:labels]) unless params[:labels].nil? - - unless params[:milestone].nil? - issues = filter_issues_milestone(issues, params[:milestone]) - end - - issues.reorder(issuable_order_by => issuable_sort) - present paginate(issues), with: Entities::Issue - end - - # Get a single project issue - # - # Parameters: - # id (required) - The ID of a project - # issue_id (required) - The ID of a project issue - # Example Request: - # GET /projects/:id/issues/:issue_id - get ":id/issues/:issue_id" do - @issue = user_project.issues.find(params[:issue_id]) - present @issue, with: Entities::Issue - end - - # Create a new project issue - # - # Parameters: - # id (required) - The ID of a project - # title (required) - The title of an issue - # description (optional) - The description of an issue - # assignee_id (optional) - The ID of a user to assign issue - # milestone_id (optional) - The ID of a milestone to assign issue - # labels (optional) - The labels of an issue - # Example Request: - # POST /projects/:id/issues - post ":id/issues" do - required_attributes! [:title] - attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id] - - # Validate label names in advance - if (errors = validate_label_params(params)).any? - render_api_error!({ labels: errors }, 400) - end - - issue = ::Issues::CreateService.new(user_project, current_user, attrs).execute - - if issue.valid? - # Find or create labels and attach to issue. Labels are valid because - # we already checked its name, so there can't be an error here - if params[:labels].present? - issue.add_labels_by_names(params[:labels].split(',')) - end - - present issue, with: Entities::Issue - else - render_validation_error!(issue) - end - end - - # Update an existing issue - # - # Parameters: - # id (required) - The ID of a project - # issue_id (required) - The ID of a project issue - # title (optional) - The title of an issue - # description (optional) - The description of an issue - # assignee_id (optional) - The ID of a user to assign issue - # milestone_id (optional) - The ID of a milestone to assign issue - # labels (optional) - The labels of an issue - # state_event (optional) - The state event of an issue (close|reopen) - # Example Request: - # PUT /projects/:id/issues/:issue_id - put ":id/issues/:issue_id" do - issue = user_project.issues.find(params[:issue_id]) - authorize! :modify_issue, issue - attrs = attributes_for_keys [:title, :description, :assignee_id, :milestone_id, :state_event] - - # Validate label names in advance - if (errors = validate_label_params(params)).any? - render_api_error!({ labels: errors }, 400) - end - - issue = ::Issues::UpdateService.new(user_project, current_user, attrs).execute(issue) - - if issue.valid? - # Find or create labels and attach to issue. Labels are valid because - # we already checked its name, so there can't be an error here - unless params[:labels].nil? - issue.remove_labels - # Create and add labels to the new created issue - issue.add_labels_by_names(params[:labels].split(',')) - end - - present issue, with: Entities::Issue - else - render_validation_error!(issue) - end - end - - # Delete a project issue (deprecated) - # - # Parameters: - # id (required) - The ID of a project - # issue_id (required) - The ID of a project issue - # Example Request: - # DELETE /projects/:id/issues/:issue_id - delete ":id/issues/:issue_id" do - not_allowed! - end - end - end -end diff --git a/lib/api/labels.rb b/lib/api/labels.rb deleted file mode 100644 index 78ca58ad0d13462b83473724cdb169eef4673e09..0000000000000000000000000000000000000000 --- a/lib/api/labels.rb +++ /dev/null @@ -1,98 +0,0 @@ -module API - # Labels API - class Labels < Grape::API - before { authenticate! } - - resource :projects do - # Get all labels of the project - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/labels - get ':id/labels' do - present user_project.labels, with: Entities::Label - end - - # Creates a new label - # - # Parameters: - # id (required) - The ID of a project - # name (required) - The name of the label to be deleted - # color (required) - Color of the label given in 6-digit hex - # notation with leading '#' sign (e.g. #FFAABB) - # Example Request: - # POST /projects/:id/labels - post ':id/labels' do - authorize! :admin_label, user_project - required_attributes! [:name, :color] - - attrs = attributes_for_keys [:name, :color] - label = user_project.find_label(attrs[:name]) - - conflict!('Label already exists') if label - - label = user_project.labels.create(attrs) - - if label.valid? - present label, with: Entities::Label - else - render_validation_error!(label) - end - end - - # Deletes an existing label - # - # Parameters: - # id (required) - The ID of a project - # name (required) - The name of the label to be deleted - # - # Example Request: - # DELETE /projects/:id/labels - delete ':id/labels' do - authorize! :admin_label, user_project - required_attributes! [:name] - - label = user_project.find_label(params[:name]) - not_found!('Label') unless label - - label.destroy - end - - # Updates an existing label. At least one optional parameter is required. - # - # Parameters: - # id (required) - The ID of a project - # name (required) - The name of the label to be deleted - # new_name (optional) - The new name of the label - # color (optional) - Color of the label given in 6-digit hex - # notation with leading '#' sign (e.g. #FFAABB) - # Example Request: - # PUT /projects/:id/labels - put ':id/labels' do - authorize! :admin_label, user_project - required_attributes! [:name] - - label = user_project.find_label(params[:name]) - not_found!('Label not found') unless label - - attrs = attributes_for_keys [:new_name, :color] - - if attrs.empty? - render_api_error!('Required parameters "new_name" or "color" ' \ - 'missing', - 400) - end - - # Rename new name to the actual label attribute name - attrs[:name] = attrs.delete(:new_name) if attrs.key?(:new_name) - - if label.update(attrs) - present label, with: Entities::Label - else - render_validation_error!(label) - end - end - end - end -end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb deleted file mode 100644 index f3765f5ab03909ab1e8f40c624929cf4e76439e1..0000000000000000000000000000000000000000 --- a/lib/api/merge_requests.rb +++ /dev/null @@ -1,249 +0,0 @@ -module API - # MergeRequest API - class MergeRequests < Grape::API - before { authenticate! } - - resource :projects do - helpers do - def handle_merge_request_errors!(errors) - if errors[:project_access].any? - error!(errors[:project_access], 422) - elsif errors[:branch_conflict].any? - error!(errors[:branch_conflict], 422) - elsif errors[:validate_fork].any? - error!(errors[:validate_fork], 422) - elsif errors[:validate_branches].any? - conflict!(errors[:validate_branches]) - end - - render_api_error!(errors, 400) - end - end - - # List merge requests - # - # Parameters: - # id (required) - The ID of a project - # state (optional) - Return requests "merged", "opened" or "closed" - # order_by (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` - # sort (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` - # - # Example: - # GET /projects/:id/merge_requests - # GET /projects/:id/merge_requests?state=opened - # GET /projects/:id/merge_requests?state=closed - # GET /projects/:id/merge_requests?order_by=created_at - # GET /projects/:id/merge_requests?order_by=updated_at - # GET /projects/:id/merge_requests?sort=desc - # GET /projects/:id/merge_requests?sort=asc - # - get ":id/merge_requests" do - authorize! :read_merge_request, user_project - merge_requests = user_project.merge_requests - - merge_requests = - case params["state"] - when "opened" then merge_requests.opened - when "closed" then merge_requests.closed - when "merged" then merge_requests.merged - else merge_requests - end - - merge_requests.reorder(issuable_order_by => issuable_sort) - present paginate(merge_requests), with: Entities::MergeRequest - end - - # Show MR - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - The ID of MR - # - # Example: - # GET /projects/:id/merge_request/:merge_request_id - # - get ":id/merge_request/:merge_request_id" do - merge_request = user_project.merge_requests.find(params[:merge_request_id]) - - authorize! :read_merge_request, merge_request - - present merge_request, with: Entities::MergeRequest - end - - # Show MR changes - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - The ID of MR - # - # Example: - # GET /projects/:id/merge_request/:merge_request_id/changes - # - get ':id/merge_request/:merge_request_id/changes' do - merge_request = user_project.merge_requests. - find(params[:merge_request_id]) - authorize! :read_merge_request, merge_request - present merge_request, with: Entities::MergeRequestChanges - end - - # Create MR - # - # Parameters: - # - # id (required) - The ID of a project - this will be the source of the merge request - # source_branch (required) - The source branch - # target_branch (required) - The target branch - # target_project - The target project of the merge request defaults to the :id of the project - # assignee_id - Assignee user ID - # title (required) - Title of MR - # description - Description of MR - # labels (optional) - Labels for MR as a comma-separated list - # - # Example: - # POST /projects/:id/merge_requests - # - post ":id/merge_requests" do - authorize! :write_merge_request, user_project - required_attributes! [:source_branch, :target_branch, :title] - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description] - - # Validate label names in advance - if (errors = validate_label_params(params)).any? - render_api_error!({ labels: errors }, 400) - end - - merge_request = ::MergeRequests::CreateService.new(user_project, current_user, attrs).execute - - if merge_request.valid? - # Find or create labels and attach to issue - if params[:labels].present? - merge_request.add_labels_by_names(params[:labels].split(",")) - end - - present merge_request, with: Entities::MergeRequest - else - handle_merge_request_errors! merge_request.errors - end - end - - # Update MR - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - ID of MR - # source_branch - The source branch - # target_branch - The target branch - # assignee_id - Assignee user ID - # title - Title of MR - # state_event - Status of MR. (close|reopen|merge) - # description - Description of MR - # labels (optional) - Labels for a MR as a comma-separated list - # Example: - # PUT /projects/:id/merge_request/:merge_request_id - # - put ":id/merge_request/:merge_request_id" do - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event, :description] - merge_request = user_project.merge_requests.find(params[:merge_request_id]) - authorize! :modify_merge_request, merge_request - - # Validate label names in advance - if (errors = validate_label_params(params)).any? - render_api_error!({ labels: errors }, 400) - end - - merge_request = ::MergeRequests::UpdateService.new(user_project, current_user, attrs).execute(merge_request) - - if merge_request.valid? - # Find or create labels and attach to issue - unless params[:labels].nil? - merge_request.remove_labels - merge_request.add_labels_by_names(params[:labels].split(",")) - end - - present merge_request, with: Entities::MergeRequest - else - handle_merge_request_errors! merge_request.errors - end - end - - # Merge MR - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - ID of MR - # merge_commit_message (optional) - Custom merge commit message - # Example: - # PUT /projects/:id/merge_request/:merge_request_id/merge - # - put ":id/merge_request/:merge_request_id/merge" do - merge_request = user_project.merge_requests.find(params[:merge_request_id]) - - allowed = ::Gitlab::GitAccess.new(current_user, user_project). - can_push_to_branch?(merge_request.target_branch) - - if allowed - if merge_request.unchecked? - merge_request.check_if_can_be_merged - end - - if merge_request.open? - if merge_request.can_be_merged? - merge_request.automerge!(current_user, params[:merge_commit_message] || merge_request.merge_commit_message) - present merge_request, with: Entities::MergeRequest - else - render_api_error!('Branch cannot be merged', 405) - end - else - # Merge request can not be merged - # because it is already closed/merged - not_allowed! - end - else - # Merge request can not be merged - # because user dont have permissions to push into target branch - unauthorized! - end - end - - - # Get a merge request's comments - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - ID of MR - # Examples: - # GET /projects/:id/merge_request/:merge_request_id/comments - # - get ":id/merge_request/:merge_request_id/comments" do - merge_request = user_project.merge_requests.find(params[:merge_request_id]) - - authorize! :read_merge_request, merge_request - - present paginate(merge_request.notes), with: Entities::MRNote - end - - # Post comment to merge request - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - ID of MR - # note (required) - Text of comment - # Examples: - # POST /projects/:id/merge_request/:merge_request_id/comments - # - post ":id/merge_request/:merge_request_id/comments" do - required_attributes! [:note] - - merge_request = user_project.merge_requests.find(params[:merge_request_id]) - note = merge_request.notes.new(note: params[:note], project_id: user_project.id) - note.author = current_user - - if note.save - present note, with: Entities::MRNote - else - render_api_error!("Failed to save note #{note.errors.messages}", 400) - end - end - end - end -end diff --git a/lib/api/milestones.rb b/lib/api/milestones.rb deleted file mode 100644 index c5cd73943fb84ee67e76e1c5fccc26621a47a9ce..0000000000000000000000000000000000000000 --- a/lib/api/milestones.rb +++ /dev/null @@ -1,95 +0,0 @@ -module API - # Milestones API - class Milestones < Grape::API - before { authenticate! } - - resource :projects do - # Get a list of project milestones - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/milestones - get ":id/milestones" do - authorize! :read_milestone, user_project - - present paginate(user_project.milestones), with: Entities::Milestone - end - - # Get a single project milestone - # - # Parameters: - # id (required) - The ID of a project - # milestone_id (required) - The ID of a project milestone - # Example Request: - # GET /projects/:id/milestones/:milestone_id - get ":id/milestones/:milestone_id" do - authorize! :read_milestone, user_project - - @milestone = user_project.milestones.find(params[:milestone_id]) - present @milestone, with: Entities::Milestone - end - - # Create a new project milestone - # - # Parameters: - # id (required) - The ID of the project - # title (required) - The title of the milestone - # description (optional) - The description of the milestone - # due_date (optional) - The due date of the milestone - # Example Request: - # POST /projects/:id/milestones - post ":id/milestones" do - authorize! :admin_milestone, user_project - required_attributes! [:title] - attrs = attributes_for_keys [:title, :description, :due_date] - milestone = ::Milestones::CreateService.new(user_project, current_user, attrs).execute - - if milestone.valid? - present milestone, with: Entities::Milestone - else - render_api_error!("Failed to create milestone #{milestone.errors.messages}", 400) - end - end - - # Update an existing project milestone - # - # Parameters: - # id (required) - The ID of a project - # milestone_id (required) - The ID of a project milestone - # title (optional) - The title of a milestone - # description (optional) - The description of a milestone - # due_date (optional) - The due date of a milestone - # state_event (optional) - The state event of the milestone (close|activate) - # Example Request: - # PUT /projects/:id/milestones/:milestone_id - put ":id/milestones/:milestone_id" do - authorize! :admin_milestone, user_project - attrs = attributes_for_keys [:title, :description, :due_date, :state_event] - milestone = user_project.milestones.find(params[:milestone_id]) - milestone = ::Milestones::UpdateService.new(user_project, current_user, attrs).execute(milestone) - - if milestone.valid? - present milestone, with: Entities::Milestone - else - render_api_error!("Failed to update milestone #{milestone.errors.messages}", 400) - end - end - - # Get all issues for a single project milestone - # - # Parameters: - # id (required) - The ID of a project - # milestone_id (required) - The ID of a project milestone - # Example Request: - # GET /projects/:id/milestones/:milestone_id/issues - get ":id/milestones/:milestone_id/issues" do - authorize! :read_milestone, user_project - - @milestone = user_project.milestones.find(params[:milestone_id]) - present paginate(@milestone.issues), with: Entities::Issue - end - - end - end -end diff --git a/lib/api/namespaces.rb b/lib/api/namespaces.rb deleted file mode 100644 index b90ed6af5fbe6e32f92a65e57df72f3a34d49c22..0000000000000000000000000000000000000000 --- a/lib/api/namespaces.rb +++ /dev/null @@ -1,23 +0,0 @@ -module API - # namespaces API - class Namespaces < Grape::API - before do - authenticate! - authenticated_as_admin! - end - - resource :namespaces do - # Get a namespaces list - # - # Example Request: - # GET /namespaces - get do - @namespaces = Namespace.all - @namespaces = @namespaces.search(params[:search]) if params[:search].present? - @namespaces = paginate @namespaces - - present @namespaces, with: Entities::Namespace - end - end - end -end diff --git a/lib/api/notes.rb b/lib/api/notes.rb deleted file mode 100644 index 3726be7c5374c151be3e9db957a4be886b3d3537..0000000000000000000000000000000000000000 --- a/lib/api/notes.rb +++ /dev/null @@ -1,103 +0,0 @@ -module API - # Notes API - class Notes < Grape::API - before { authenticate! } - - NOTEABLE_TYPES = [Issue, MergeRequest, Snippet] - - resource :projects do - NOTEABLE_TYPES.each do |noteable_type| - noteables_str = noteable_type.to_s.underscore.pluralize - noteable_id_str = "#{noteable_type.to_s.underscore}_id" - - # Get a list of project +noteable+ notes - # - # Parameters: - # id (required) - The ID of a project - # noteable_id (required) - The ID of an issue or snippet - # Example Request: - # GET /projects/:id/issues/:noteable_id/notes - # GET /projects/:id/snippets/:noteable_id/notes - get ":id/#{noteables_str}/:#{noteable_id_str}/notes" do - @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) - present paginate(@noteable.notes), with: Entities::Note - end - - # Get a single +noteable+ note - # - # Parameters: - # id (required) - The ID of a project - # noteable_id (required) - The ID of an issue or snippet - # note_id (required) - The ID of a note - # Example Request: - # GET /projects/:id/issues/:noteable_id/notes/:note_id - # GET /projects/:id/snippets/:noteable_id/notes/:note_id - get ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do - @noteable = user_project.send(:"#{noteables_str}").find(params[:"#{noteable_id_str}"]) - @note = @noteable.notes.find(params[:note_id]) - present @note, with: Entities::Note - end - - # Create a new +noteable+ note - # - # Parameters: - # id (required) - The ID of a project - # noteable_id (required) - The ID of an issue or snippet - # body (required) - The content of a note - # Example Request: - # POST /projects/:id/issues/:noteable_id/notes - # POST /projects/:id/snippets/:noteable_id/notes - post ":id/#{noteables_str}/:#{noteable_id_str}/notes" do - required_attributes! [:body] - - opts = { - note: params[:body], - noteable_type: noteables_str.classify, - noteable_id: params[noteable_id_str] - } - - @note = ::Notes::CreateService.new(user_project, current_user, opts).execute - - if @note.valid? - present @note, with: Entities::Note - else - not_found!("Note #{@note.errors.messages}") - end - end - - # Modify existing +noteable+ note - # - # Parameters: - # id (required) - The ID of a project - # noteable_id (required) - The ID of an issue or snippet - # node_id (required) - The ID of a note - # body (required) - New content of a note - # Example Request: - # PUT /projects/:id/issues/:noteable_id/notes/:note_id - # PUT /projects/:id/snippets/:noteable_id/notes/:node_id - put ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do - required_attributes! [:body] - - authorize! :admin_note, user_project.notes.find(params[:note_id]) - - opts = { - note: params[:body], - note_id: params[:note_id], - noteable_type: noteables_str.classify, - noteable_id: params[noteable_id_str] - } - - @note = ::Notes::UpdateService.new(user_project, current_user, - opts).execute - - if @note.valid? - present @note, with: Entities::Note - else - render_api_error!("Failed to save note #{note.errors.messages}", 400) - end - end - - end - end - end -end diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb deleted file mode 100644 index be9850367b9835def0549af04147db482f12e275..0000000000000000000000000000000000000000 --- a/lib/api/project_hooks.rb +++ /dev/null @@ -1,108 +0,0 @@ -module API - # Projects API - class ProjectHooks < Grape::API - before { authenticate! } - before { authorize_admin_project } - - resource :projects do - # Get project hooks - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/hooks - get ":id/hooks" do - @hooks = paginate user_project.hooks - present @hooks, with: Entities::ProjectHook - end - - # Get a project hook - # - # Parameters: - # id (required) - The ID of a project - # hook_id (required) - The ID of a project hook - # Example Request: - # GET /projects/:id/hooks/:hook_id - get ":id/hooks/:hook_id" do - @hook = user_project.hooks.find(params[:hook_id]) - present @hook, with: Entities::ProjectHook - end - - - # Add hook to project - # - # Parameters: - # id (required) - The ID of a project - # url (required) - The hook URL - # Example Request: - # POST /projects/:id/hooks - post ":id/hooks" do - required_attributes! [:url] - attrs = attributes_for_keys [ - :url, - :push_events, - :issues_events, - :merge_requests_events, - :tag_push_events - ] - @hook = user_project.hooks.new(attrs) - - if @hook.save - present @hook, with: Entities::ProjectHook - else - if @hook.errors[:url].present? - error!("Invalid url given", 422) - end - not_found!("Project hook #{@hook.errors.messages}") - end - end - - # Update an existing project hook - # - # Parameters: - # id (required) - The ID of a project - # hook_id (required) - The ID of a project hook - # url (required) - The hook URL - # Example Request: - # PUT /projects/:id/hooks/:hook_id - put ":id/hooks/:hook_id" do - @hook = user_project.hooks.find(params[:hook_id]) - required_attributes! [:url] - attrs = attributes_for_keys [ - :url, - :push_events, - :issues_events, - :merge_requests_events, - :tag_push_events - ] - - if @hook.update_attributes attrs - present @hook, with: Entities::ProjectHook - else - if @hook.errors[:url].present? - error!("Invalid url given", 422) - end - not_found!("Project hook #{@hook.errors.messages}") - end - end - - # Deletes project hook. This is an idempotent function. - # - # Parameters: - # id (required) - The ID of a project - # hook_id (required) - The ID of hook to delete - # Example Request: - # DELETE /projects/:id/hooks/:hook_id - delete ":id/hooks/:hook_id" do - required_attributes! [:hook_id] - - begin - @hook = ProjectHook.find(params[:hook_id]) - @hook.destroy - rescue - # ProjectHook can raise Error if hook_id not found - end - end - end - end -end diff --git a/lib/api/project_members.rb b/lib/api/project_members.rb deleted file mode 100644 index c756bb479fc2bc01507b99a50b30fb6bc4f0e974..0000000000000000000000000000000000000000 --- a/lib/api/project_members.rb +++ /dev/null @@ -1,106 +0,0 @@ -module API - # Projects members API - class ProjectMembers < Grape::API - before { authenticate! } - - resource :projects do - - # Get a project team members - # - # Parameters: - # id (required) - The ID of a project - # query - Query string - # Example Request: - # GET /projects/:id/members - get ":id/members" do - if params[:query].present? - @members = paginate user_project.users.where("username LIKE ?", "%#{params[:query]}%") - else - @members = paginate user_project.users - end - present @members, with: Entities::ProjectMember, project: user_project - end - - # Get a project team members - # - # Parameters: - # id (required) - The ID of a project - # user_id (required) - The ID of a user - # Example Request: - # GET /projects/:id/members/:user_id - get ":id/members/:user_id" do - @member = user_project.users.find params[:user_id] - present @member, with: Entities::ProjectMember, project: user_project - end - - # Add a new project team member - # - # Parameters: - # id (required) - The ID of a project - # user_id (required) - The ID of a user - # access_level (required) - Project access level - # Example Request: - # POST /projects/:id/members - post ":id/members" do - authorize! :admin_project, user_project - required_attributes! [:user_id, :access_level] - - # either the user is already a team member or a new one - project_member = user_project.project_member_by_id(params[:user_id]) - if project_member.nil? - project_member = user_project.project_members.new( - user_id: params[:user_id], - access_level: params[:access_level] - ) - end - - if project_member.save - @member = project_member.user - present @member, with: Entities::ProjectMember, project: user_project - else - handle_member_errors project_member.errors - end - end - - # Update project team member - # - # Parameters: - # id (required) - The ID of a project - # user_id (required) - The ID of a team member - # access_level (required) - Project access level - # Example Request: - # PUT /projects/:id/members/:user_id - put ":id/members/:user_id" do - authorize! :admin_project, user_project - required_attributes! [:access_level] - - project_member = user_project.project_members.find_by(user_id: params[:user_id]) - not_found!("User can not be found") if project_member.nil? - - if project_member.update_attributes(access_level: params[:access_level]) - @member = project_member.user - present @member, with: Entities::ProjectMember, project: user_project - else - handle_member_errors project_member.errors - end - end - - # Remove a team member from project - # - # Parameters: - # id (required) - The ID of a project - # user_id (required) - The ID of a team member - # Example Request: - # DELETE /projects/:id/members/:user_id - delete ":id/members/:user_id" do - authorize! :admin_project, user_project - project_member = user_project.project_members.find_by(user_id: params[:user_id]) - unless project_member.nil? - project_member.destroy - else - { message: "Access revoked", id: params[:user_id].to_i } - end - end - end - end -end diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb deleted file mode 100644 index 54f2555903f0e3ed11f81f8a09e517ae296a7cf6..0000000000000000000000000000000000000000 --- a/lib/api/project_snippets.rb +++ /dev/null @@ -1,124 +0,0 @@ -module API - # Projects API - class ProjectSnippets < Grape::API - before { authenticate! } - - resource :projects do - helpers do - def handle_project_member_errors(errors) - if errors[:project_access].any? - error!(errors[:project_access], 422) - end - not_found! - end - end - - # Get a project snippets - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/snippets - get ":id/snippets" do - present paginate(user_project.snippets), with: Entities::ProjectSnippet - end - - # Get a project snippet - # - # Parameters: - # id (required) - The ID of a project - # snippet_id (required) - The ID of a project snippet - # Example Request: - # GET /projects/:id/snippets/:snippet_id - get ":id/snippets/:snippet_id" do - @snippet = user_project.snippets.find(params[:snippet_id]) - present @snippet, with: Entities::ProjectSnippet - end - - # Create a new project snippet - # - # Parameters: - # id (required) - The ID of a project - # title (required) - The title of a snippet - # file_name (required) - The name of a snippet file - # code (required) - The content of a snippet - # visibility_level (required) - The snippet's visibility - # Example Request: - # POST /projects/:id/snippets - post ":id/snippets" do - authorize! :write_project_snippet, user_project - required_attributes! [:title, :file_name, :code, :visibility_level] - - attrs = attributes_for_keys [:title, :file_name, :visibility_level] - attrs[:content] = params[:code] if params[:code].present? - @snippet = CreateSnippetService.new(user_project, current_user, - attrs).execute - - if @snippet.errors.any? - render_validation_error!(@snippet) - else - present @snippet, with: Entities::ProjectSnippet - end - end - - # Update an existing project snippet - # - # Parameters: - # id (required) - The ID of a project - # snippet_id (required) - The ID of a project snippet - # title (optional) - The title of a snippet - # file_name (optional) - The name of a snippet file - # code (optional) - The content of a snippet - # visibility_level (optional) - The snippet's visibility - # Example Request: - # PUT /projects/:id/snippets/:snippet_id - put ":id/snippets/:snippet_id" do - @snippet = user_project.snippets.find(params[:snippet_id]) - authorize! :modify_project_snippet, @snippet - - attrs = attributes_for_keys [:title, :file_name, :visibility_level] - attrs[:content] = params[:code] if params[:code].present? - - UpdateSnippetService.new(user_project, current_user, @snippet, - attrs).execute - if @snippet.errors.any? - render_validation_error!(@snippet) - else - present @snippet, with: Entities::ProjectSnippet - end - end - - # Delete a project snippet - # - # Parameters: - # id (required) - The ID of a project - # snippet_id (required) - The ID of a project snippet - # Example Request: - # DELETE /projects/:id/snippets/:snippet_id - delete ":id/snippets/:snippet_id" do - begin - @snippet = user_project.snippets.find(params[:snippet_id]) - authorize! :modify_project_snippet, @snippet - @snippet.destroy - rescue - not_found!('Snippet') - end - end - - # Get a raw project snippet - # - # Parameters: - # id (required) - The ID of a project - # snippet_id (required) - The ID of a project snippet - # Example Request: - # GET /projects/:id/snippets/:snippet_id/raw - get ":id/snippets/:snippet_id/raw" do - @snippet = user_project.snippets.find(params[:snippet_id]) - - env['api.format'] = :txt - content_type 'text/plain' - present @snippet.content - end - end - end -end diff --git a/lib/api/projects.rb b/lib/api/projects.rb deleted file mode 100644 index e3fff79d68f5e6115a7314cca2bdf3081bd16bdc..0000000000000000000000000000000000000000 --- a/lib/api/projects.rb +++ /dev/null @@ -1,323 +0,0 @@ -module API - # Projects API - class Projects < Grape::API - before { authenticate! } - - resource :projects do - helpers do - def map_public_to_visibility_level(attrs) - publik = attrs.delete(:public) - publik = parse_boolean(publik) - attrs[:visibility_level] = Gitlab::VisibilityLevel::PUBLIC if !attrs[:visibility_level].present? && publik == true - attrs - end - - def filter_projects(projects) - # If the archived parameter is passed, limit results accordingly - if params[:archived].present? - projects = projects.where(archived: parse_boolean(params[:archived])) - end - - if params[:search].present? - projects = projects.search(params[:search]) - end - - projects.reorder(project_order_by => project_sort) - end - - def project_order_by - order_fields = %w(id name path created_at updated_at last_activity_at) - - if order_fields.include?(params['order_by']) - params['order_by'] - else - 'created_at' - end - end - - def project_sort - if params["sort"] == 'asc' - :asc - else - :desc - end - end - end - - # Get a projects list for authenticated user - # - # Example Request: - # GET /projects - get do - @projects = current_user.authorized_projects - @projects = filter_projects(@projects) - @projects = paginate @projects - present @projects, with: Entities::Project - end - - # Get an owned projects list for authenticated user - # - # Example Request: - # GET /projects/owned - get '/owned' do - @projects = current_user.owned_projects - @projects = filter_projects(@projects) - @projects = paginate @projects - present @projects, with: Entities::Project - end - - # Get all projects for admin user - # - # Example Request: - # GET /projects/all - get '/all' do - authenticated_as_admin! - @projects = Project.all - @projects = filter_projects(@projects) - @projects = paginate @projects - present @projects, with: Entities::Project - end - - # Get a single project - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id - get ":id" do - present user_project, with: Entities::ProjectWithAccess, user: current_user - end - - # Get events for a single project - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/events - get ":id/events" do - events = paginate user_project.events.recent - present events, with: Entities::Event - end - - # Create new project - # - # Parameters: - # name (required) - name for new project - # description (optional) - short project description - # issues_enabled (optional) - # merge_requests_enabled (optional) - # wiki_enabled (optional) - # snippets_enabled (optional) - # namespace_id (optional) - defaults to user namespace - # public (optional) - if true same as setting visibility_level = 20 - # visibility_level (optional) - 0 by default - # import_url (optional) - # Example Request - # POST /projects - post do - required_attributes! [:name] - attrs = attributes_for_keys [:name, - :path, - :description, - :issues_enabled, - :merge_requests_enabled, - :wiki_enabled, - :snippets_enabled, - :namespace_id, - :public, - :visibility_level, - :import_url] - attrs = map_public_to_visibility_level(attrs) - @project = ::Projects::CreateService.new(current_user, attrs).execute - if @project.saved? - present @project, with: Entities::Project - else - if @project.errors[:limit_reached].present? - error!(@project.errors[:limit_reached], 403) - end - render_validation_error!(@project) - end - end - - # Create new project for a specified user. Only available to admin users. - # - # Parameters: - # user_id (required) - The ID of a user - # name (required) - name for new project - # description (optional) - short project description - # default_branch (optional) - 'master' by default - # issues_enabled (optional) - # merge_requests_enabled (optional) - # wiki_enabled (optional) - # snippets_enabled (optional) - # public (optional) - if true same as setting visibility_level = 20 - # visibility_level (optional) - # import_url (optional) - # Example Request - # POST /projects/user/:user_id - post "user/:user_id" do - authenticated_as_admin! - user = User.find(params[:user_id]) - attrs = attributes_for_keys [:name, - :description, - :default_branch, - :issues_enabled, - :merge_requests_enabled, - :wiki_enabled, - :snippets_enabled, - :public, - :visibility_level, - :import_url] - attrs = map_public_to_visibility_level(attrs) - @project = ::Projects::CreateService.new(user, attrs).execute - if @project.saved? - present @project, with: Entities::Project - else - render_validation_error!(@project) - end - end - - # Fork new project for the current user. - # - # Parameters: - # id (required) - The ID of a project - # Example Request - # POST /projects/fork/:id - post 'fork/:id' do - @forked_project = - ::Projects::ForkService.new(user_project, - current_user).execute - if @forked_project.errors.any? - conflict!(@forked_project.errors.messages) - else - present @forked_project, with: Entities::Project - end - end - - # Update an existing project - # - # Parameters: - # id (required) - the id of a project - # name (optional) - name of a project - # path (optional) - path of a project - # description (optional) - short project description - # issues_enabled (optional) - # merge_requests_enabled (optional) - # wiki_enabled (optional) - # snippets_enabled (optional) - # public (optional) - if true same as setting visibility_level = 20 - # visibility_level (optional) - visibility level of a project - # Example Request - # PUT /projects/:id - put ':id' do - attrs = attributes_for_keys [:name, - :path, - :description, - :default_branch, - :issues_enabled, - :merge_requests_enabled, - :wiki_enabled, - :snippets_enabled, - :public, - :visibility_level] - attrs = map_public_to_visibility_level(attrs) - authorize_admin_project - authorize! :rename_project, user_project if attrs[:name].present? - if attrs[:visibility_level].present? - authorize! :change_visibility_level, user_project - end - - ::Projects::UpdateService.new(user_project, - current_user, attrs).execute - - if user_project.errors.any? - render_validation_error!(user_project) - else - present user_project, with: Entities::Project - end - end - - # Remove project - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # DELETE /projects/:id - delete ":id" do - authorize! :remove_project, user_project - ::Projects::DestroyService.new(user_project, current_user, {}).execute - end - - # Mark this project as forked from another - # - # Parameters: - # id: (required) - The ID of the project being marked as a fork - # forked_from_id: (required) - The ID of the project it was forked from - # Example Request: - # POST /projects/:id/fork/:forked_from_id - post ":id/fork/:forked_from_id" do - authenticated_as_admin! - forked_from_project = find_project(params[:forked_from_id]) - unless forked_from_project.nil? - if user_project.forked_from_project.nil? - user_project.create_forked_project_link(forked_to_project_id: user_project.id, forked_from_project_id: forked_from_project.id) - else - render_api_error!("Project already forked", 409) - end - else - not_found!("Source Project") - end - - end - - # Remove a forked_from relationship - # - # Parameters: - # id: (required) - The ID of the project being marked as a fork - # Example Request: - # DELETE /projects/:id/fork - delete ":id/fork" do - authenticated_as_admin! - unless user_project.forked_project_link.nil? - user_project.forked_project_link.destroy - end - end - # search for projects current_user has access to - # - # Parameters: - # query (required) - A string contained in the project name - # per_page (optional) - number of projects to return per page - # page (optional) - the page to retrieve - # Example Request: - # GET /projects/search/:query - get "/search/:query" do - ids = current_user.authorized_projects.map(&:id) - visibility_levels = [ Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PUBLIC ] - projects = Project.where("(id in (?) OR visibility_level in (?)) AND (name LIKE (?))", ids, visibility_levels, "%#{params[:query]}%") - sort = params[:sort] == 'desc' ? 'desc' : 'asc' - - projects = case params["order_by"] - when 'id' then projects.order("id #{sort}") - when 'name' then projects.order("name #{sort}") - when 'created_at' then projects.order("created_at #{sort}") - when 'last_activity_at' then projects.order("last_activity_at #{sort}") - else projects - end - - present paginate(projects), with: Entities::Project - end - - - # Get a users list - # - # Example Request: - # GET /users - get ':id/users' do - @users = User.where(id: user_project.team.users.map(&:id)) - @users = @users.search(params[:search]) if params[:search].present? - @users = paginate @users - present @users, with: Entities::UserBasic - end - end - end -end diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb deleted file mode 100644 index 1fbf3dca3c6faff82f943b72b7b2c1aada99330f..0000000000000000000000000000000000000000 --- a/lib/api/repositories.rb +++ /dev/null @@ -1,190 +0,0 @@ -require 'mime/types' - -module API - # Projects API - class Repositories < Grape::API - before { authenticate! } - before { authorize! :download_code, user_project } - - resource :projects do - helpers do - def handle_project_member_errors(errors) - if errors[:project_access].any? - error!(errors[:project_access], 422) - end - not_found! - end - end - - # Get a project repository tags - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/repository/tags - get ":id/repository/tags" do - present user_project.repo.tags.sort_by(&:name).reverse, - with: Entities::RepoTag, project: user_project - end - - # Create tag - # - # Parameters: - # id (required) - The ID of a project - # tag_name (required) - The name of the tag - # ref (required) - Create tag from commit sha or branch - # message (optional) - Specifying a message creates an annotated tag. - # Example Request: - # POST /projects/:id/repository/tags - post ':id/repository/tags' do - authorize_push_project - message = params[:message] || nil - result = CreateTagService.new(user_project, current_user). - execute(params[:tag_name], params[:ref], message) - - if result[:status] == :success - present result[:tag], - with: Entities::RepoTag, - project: user_project - else - render_api_error!(result[:message], 400) - end - end - - # Get a project repository tree - # - # Parameters: - # id (required) - The ID of a project - # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used - # Example Request: - # GET /projects/:id/repository/tree - get ':id/repository/tree' do - ref = params[:ref_name] || user_project.try(:default_branch) || 'master' - path = params[:path] || nil - - commit = user_project.repository.commit(ref) - not_found!('Tree') unless commit - - tree = user_project.repository.tree(commit.id, path) - - present tree.sorted_entries, with: Entities::RepoTreeObject - end - - # Get a raw file contents - # - # Parameters: - # id (required) - The ID of a project - # sha (required) - The commit or branch name - # filepath (required) - The path to the file to display - # Example Request: - # GET /projects/:id/repository/blobs/:sha - get [ ":id/repository/blobs/:sha", ":id/repository/commits/:sha/blob" ] do - required_attributes! [:filepath] - - ref = params[:sha] - - repo = user_project.repository - - commit = repo.commit(ref) - not_found! "Commit" unless commit - - blob = Gitlab::Git::Blob.find(repo, commit.id, params[:filepath]) - not_found! "File" unless blob - - content_type 'text/plain' - present blob.data - end - - # Get a raw blob contents by blob sha - # - # Parameters: - # id (required) - The ID of a project - # sha (required) - The blob's sha - # Example Request: - # GET /projects/:id/repository/raw_blobs/:sha - get ':id/repository/raw_blobs/:sha' do - ref = params[:sha] - - repo = user_project.repository - - begin - blob = Gitlab::Git::Blob.raw(repo, ref) - rescue - not_found! 'Blob' - end - - not_found! 'Blob' unless blob - - env['api.format'] = :txt - - content_type blob.mime_type - present blob.data - end - - # Get a an archive of the repository - # - # Parameters: - # id (required) - The ID of a project - # sha (optional) - the commit sha to download defaults to the tip of the default branch - # Example Request: - # GET /projects/:id/repository/archive - get ':id/repository/archive', - requirements: { format: Gitlab::Regex.archive_formats_regex } do - authorize! :download_code, user_project - - begin - file_path = ArchiveRepositoryService.new( - user_project, - params[:sha], - params[:format] - ).execute - rescue - not_found!('File') - end - - if file_path && File.exists?(file_path) - data = File.open(file_path, 'rb').read - basename = File.basename(file_path) - header['Content-Disposition'] = "attachment; filename=\"#{basename}\"" - content_type MIME::Types.type_for(file_path).first.content_type - env['api.format'] = :binary - present data - else - redirect request.fullpath - end - end - - # Compare two branches, tags or commits - # - # Parameters: - # id (required) - The ID of a project - # from (required) - the commit sha or branch name - # to (required) - the commit sha or branch name - # Example Request: - # GET /projects/:id/repository/compare?from=master&to=feature - get ':id/repository/compare' do - authorize! :download_code, user_project - required_attributes! [:from, :to] - compare = Gitlab::Git::Compare.new(user_project.repository.raw_repository, params[:from], params[:to]) - present compare, with: Entities::Compare - end - - # Get repository contributors - # - # Parameters: - # id (required) - The ID of a project - # Example Request: - # GET /projects/:id/repository/contributors - get ':id/repository/contributors' do - authorize! :download_code, user_project - - begin - present user_project.repository.contributors, - with: Entities::Contributor - rescue - not_found! - end - end - end - end -end diff --git a/lib/api/services.rb b/lib/api/services.rb deleted file mode 100644 index 3ad59cf3adf6ab95629b8fed1aa175f26efafeca..0000000000000000000000000000000000000000 --- a/lib/api/services.rb +++ /dev/null @@ -1,78 +0,0 @@ -module API - # Projects API - class Services < Grape::API - before { authenticate! } - before { authorize_admin_project } - - resource :projects do - # Set GitLab CI service for project - # - # Parameters: - # token (required) - CI project token - # project_url (required) - CI project url - # - # Example Request: - # PUT /projects/:id/services/gitlab-ci - put ":id/services/gitlab-ci" do - required_attributes! [:token, :project_url] - attrs = attributes_for_keys [:token, :project_url] - user_project.build_missing_services - - if user_project.gitlab_ci_service.update_attributes(attrs.merge(active: true)) - true - else - not_found! - end - end - - # Delete GitLab CI service settings - # - # Example Request: - # DELETE /projects/:id/services/gitlab-ci - delete ":id/services/gitlab-ci" do - if user_project.gitlab_ci_service - user_project.gitlab_ci_service.update_attributes( - active: false, - token: nil, - project_url: nil - ) - end - end - - # Set Hipchat service for project - # - # Parameters: - # token (required) - Hipchat token - # room (required) - Hipchat room name - # - # Example Request: - # PUT /projects/:id/services/hipchat - put ':id/services/hipchat' do - required_attributes! [:token, :room] - attrs = attributes_for_keys [:token, :room] - user_project.build_missing_services - - if user_project.hipchat_service.update_attributes( - attrs.merge(active: true)) - true - else - not_found! - end - end - - # Delete Hipchat service settings - # - # Example Request: - # DELETE /projects/:id/services/hipchat - delete ':id/services/hipchat' do - if user_project.hipchat_service - user_project.hipchat_service.update_attributes( - active: false, - token: nil, - room: nil - ) - end - end - end - end -end diff --git a/lib/api/session.rb b/lib/api/session.rb deleted file mode 100644 index cc6468959142170b5ac3a06145cf27aa5551149e..0000000000000000000000000000000000000000 --- a/lib/api/session.rb +++ /dev/null @@ -1,21 +0,0 @@ -module API - # Users API - class Session < Grape::API - # Login to get token - # - # Parameters: - # login (*required) - user login - # email (*required) - user email - # password (required) - user password - # - # Example Request: - # POST /session - post "/session" do - auth = Gitlab::Auth.new - user = auth.find(params[:email] || params[:login], params[:password]) - - return unauthorized! unless user - present user, with: Entities::UserLogin - end - end -end diff --git a/lib/api/system_hooks.rb b/lib/api/system_hooks.rb deleted file mode 100644 index 518964db50d3739a5472771b9f1f3a8e0ab9b1e4..0000000000000000000000000000000000000000 --- a/lib/api/system_hooks.rb +++ /dev/null @@ -1,70 +0,0 @@ -module API - # Hooks API - class SystemHooks < Grape::API - before do - authenticate! - authenticated_as_admin! - end - - resource :hooks do - # Get the list of system hooks - # - # Example Request: - # GET /hooks - get do - @hooks = SystemHook.all - present @hooks, with: Entities::Hook - end - - # Create new system hook - # - # Parameters: - # url (required) - url for system hook - # Example Request - # POST /hooks - post do - attrs = attributes_for_keys [:url] - required_attributes! [:url] - @hook = SystemHook.new attrs - if @hook.save - present @hook, with: Entities::Hook - else - not_found! - end - end - - # Test a hook - # - # Example Request - # GET /hooks/:id - get ":id" do - @hook = SystemHook.find(params[:id]) - data = { - event_name: "project_create", - name: "Ruby", - path: "ruby", - project_id: 1, - owner_name: "Someone", - owner_email: "example@gitlabhq.com" - } - @hook.execute(data) - data - end - - # Delete a hook. This is an idempotent function. - # - # Parameters: - # id (required) - ID of the hook - # Example Request: - # DELETE /hooks/:id - delete ":id" do - begin - @hook = SystemHook.find(params[:id]) - @hook.destroy - rescue - # SystemHook raises an Error if no hook with id found - end - end - end - end -end diff --git a/lib/api/users.rb b/lib/api/users.rb deleted file mode 100644 index 032a5d76e4394027129936b6c2bfa8a1cae118bc..0000000000000000000000000000000000000000 --- a/lib/api/users.rb +++ /dev/null @@ -1,264 +0,0 @@ -module API - # Users API - class Users < Grape::API - before { authenticate! } - - resource :users do - # Get a users list - # - # Example Request: - # GET /users - get do - @users = User.all - @users = @users.active if params[:active].present? - @users = @users.search(params[:search]) if params[:search].present? - @users = paginate @users - - if current_user.is_admin? - present @users, with: Entities::UserFull - else - present @users, with: Entities::UserBasic - end - end - - # Get a single user - # - # Parameters: - # id (required) - The ID of a user - # Example Request: - # GET /users/:id - get ":id" do - @user = User.find(params[:id]) - - if current_user.is_admin? - present @user, with: Entities::UserFull - else - present @user, with: Entities::UserBasic - end - end - - # Create user. Available only for admin - # - # Parameters: - # email (required) - Email - # password (required) - Password - # name (required) - Name - # username (required) - Name - # skype - Skype ID - # linkedin - Linkedin - # twitter - Twitter account - # website_url - Website url - # projects_limit - Number of projects user can create - # extern_uid - External authentication provider UID - # provider - External provider - # bio - Bio - # admin - User is admin - true or false (default) - # can_create_group - User can create groups - true or false - # confirm - Require user confirmation - true (default) or false - # Example Request: - # POST /users - post do - authenticated_as_admin! - required_attributes! [:email, :password, :name, :username] - attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :bio, :can_create_group, :admin, :confirm] - admin = attrs.delete(:admin) - confirm = !(attrs.delete(:confirm) =~ (/(false|f|no|0)$/i)) - user = User.build_user(attrs) - user.admin = admin unless admin.nil? - user.skip_confirmation! unless confirm - - identity_attrs = attributes_for_keys [:provider, :extern_uid] - if identity_attrs.any? - user.identities.build(identity_attrs) - end - - if user.save - present user, with: Entities::UserFull - else - conflict!('Email has already been taken') if User. - where(email: user.email). - count > 0 - - conflict!('Username has already been taken') if User. - where(username: user.username). - count > 0 - - render_validation_error!(user) - end - end - - # Update user. Available only for admin - # - # Parameters: - # email - Email - # name - Name - # password - Password - # skype - Skype ID - # linkedin - Linkedin - # twitter - Twitter account - # website_url - Website url - # projects_limit - Limit projects each user can create - # bio - Bio - # admin - User is admin - true or false (default) - # can_create_group - User can create groups - true or false - # Example Request: - # PUT /users/:id - put ":id" do - authenticated_as_admin! - - attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :projects_limit, :username, :bio, :can_create_group, :admin] - user = User.find(params[:id]) - not_found!('User') unless user - - admin = attrs.delete(:admin) - user.admin = admin unless admin.nil? - - conflict!('Email has already been taken') if attrs[:email] && - User.where(email: attrs[:email]). - where.not(id: user.id).count > 0 - - conflict!('Username has already been taken') if attrs[:username] && - User.where(username: attrs[:username]). - where.not(id: user.id).count > 0 - - if user.update_attributes(attrs) - present user, with: Entities::UserFull - else - render_validation_error!(user) - end - end - - # Add ssh key to a specified user. Only available to admin users. - # - # Parameters: - # id (required) - The ID of a user - # key (required) - New SSH Key - # title (required) - New SSH Key's title - # Example Request: - # POST /users/:id/keys - post ":id/keys" do - authenticated_as_admin! - required_attributes! [:title, :key] - - user = User.find(params[:id]) - attrs = attributes_for_keys [:title, :key] - key = user.keys.new attrs - if key.save - present key, with: Entities::SSHKey - else - render_validation_error!(key) - end - end - - # Get ssh keys of a specified user. Only available to admin users. - # - # Parameters: - # uid (required) - The ID of a user - # Example Request: - # GET /users/:uid/keys - get ':uid/keys' do - authenticated_as_admin! - user = User.find_by(id: params[:uid]) - not_found!('User') unless user - - present user.keys, with: Entities::SSHKey - end - - # Delete existing ssh key of a specified user. Only available to admin - # users. - # - # Parameters: - # uid (required) - The ID of a user - # id (required) - SSH Key ID - # Example Request: - # DELETE /users/:uid/keys/:id - delete ':uid/keys/:id' do - authenticated_as_admin! - user = User.find_by(id: params[:uid]) - not_found!('User') unless user - - begin - key = user.keys.find params[:id] - key.destroy - rescue ActiveRecord::RecordNotFound - not_found!('Key') - end - end - - # Delete user. Available only for admin - # - # Example Request: - # DELETE /users/:id - delete ":id" do - authenticated_as_admin! - user = User.find_by(id: params[:id]) - - if user - user.destroy - else - not_found!('User') - end - end - end - - resource :user do - # Get currently authenticated user - # - # Example Request: - # GET /user - get do - present @current_user, with: Entities::UserLogin - end - - # Get currently authenticated user's keys - # - # Example Request: - # GET /user/keys - get "keys" do - present current_user.keys, with: Entities::SSHKey - end - - # Get single key owned by currently authenticated user - # - # Example Request: - # GET /user/keys/:id - get "keys/:id" do - key = current_user.keys.find params[:id] - present key, with: Entities::SSHKey - end - - # Add new ssh key to currently authenticated user - # - # Parameters: - # key (required) - New SSH Key - # title (required) - New SSH Key's title - # Example Request: - # POST /user/keys - post "keys" do - required_attributes! [:title, :key] - - attrs = attributes_for_keys [:title, :key] - key = current_user.keys.new attrs - if key.save - present key, with: Entities::SSHKey - else - render_validation_error!(key) - end - end - - # Delete existing ssh key of currently authenticated user - # - # Parameters: - # id (required) - SSH Key ID - # Example Request: - # DELETE /user/keys/:id - delete "keys/:id" do - begin - key = current_user.keys.find params[:id] - key.destroy - rescue - end - end - end - end -end diff --git a/lib/assets/.gitkeep b/lib/assets/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/lib/backup/database.rb b/lib/backup/database.rb deleted file mode 100644 index 9ab6aca276da7a274b464b404efafc62878c7605..0000000000000000000000000000000000000000 --- a/lib/backup/database.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'yaml' - -module Backup - class Database - attr_reader :config, :db_dir - - def initialize - @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env] - @db_dir = File.join(Gitlab.config.backup.path, 'db') - FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir) - end - - def dump - success = case config["adapter"] - when /^mysql/ then - $progress.print "Dumping MySQL database #{config['database']} ... " - system('mysqldump', *mysql_args, config['database'], out: db_file_name) - when "postgresql" then - $progress.print "Dumping PostgreSQL database #{config['database']} ... " - pg_env - system('pg_dump', config['database'], out: db_file_name) - end - report_success(success) - abort 'Backup failed' unless success - end - - def restore - success = case config["adapter"] - when /^mysql/ then - $progress.print "Restoring MySQL database #{config['database']} ... " - system('mysql', *mysql_args, config['database'], in: db_file_name) - when "postgresql" then - $progress.print "Restoring PostgreSQL database #{config['database']} ... " - # Drop all tables because PostgreSQL DB dumps do not contain DROP TABLE - # statements like MySQL. - Rake::Task["gitlab:db:drop_all_tables"].invoke - Rake::Task["gitlab:db:drop_all_postgres_sequences"].invoke - pg_env - system('psql', config['database'], '-f', db_file_name) - end - report_success(success) - abort 'Restore failed' unless success - end - - protected - - def db_file_name - File.join(db_dir, 'database.sql') - end - - def mysql_args - args = { - 'host' => '--host', - 'port' => '--port', - 'socket' => '--socket', - 'username' => '--user', - 'encoding' => '--default-character-set', - 'password' => '--password' - } - args.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact - end - - def pg_env - ENV['PGUSER'] = config["username"] if config["username"] - ENV['PGHOST'] = config["host"] if config["host"] - ENV['PGPORT'] = config["port"].to_s if config["port"] - ENV['PGPASSWORD'] = config["password"].to_s if config["password"] - end - - def report_success(success) - if success - $progress.puts '[DONE]'.green - else - $progress.puts '[FAILED]'.red - end - end - end -end diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb deleted file mode 100644 index b69aebf9fe11a18339b159a4c37d99a04a7e83f0..0000000000000000000000000000000000000000 --- a/lib/backup/manager.rb +++ /dev/null @@ -1,170 +0,0 @@ -module Backup - class Manager - def pack - # saving additional informations - s = {} - s[:db_version] = "#{ActiveRecord::Migrator.current_version}" - s[:backup_created_at] = Time.now - s[:gitlab_version] = Gitlab::VERSION - s[:tar_version] = tar_version - s[:skipped] = ENV["SKIP"] - tar_file = "#{s[:backup_created_at].to_i}_gitlab_backup.tar" - - Dir.chdir(Gitlab.config.backup.path) do - File.open("#{Gitlab.config.backup.path}/backup_information.yml", - "w+") do |file| - file << s.to_yaml.gsub(/^---\n/,'') - end - - FileUtils.chmod(0700, folders_to_backup) - - # create archive - $progress.print "Creating backup archive: #{tar_file} ... " - orig_umask = File.umask(0077) - if Kernel.system('tar', '-cf', tar_file, *backup_contents) - $progress.puts "done".green - else - puts "creating archive #{tar_file} failed".red - abort 'Backup failed' - end - File.umask(orig_umask) - - upload(tar_file) - end - end - - def upload(tar_file) - remote_directory = Gitlab.config.backup.upload.remote_directory - $progress.print "Uploading backup archive to remote storage #{remote_directory} ... " - - connection_settings = Gitlab.config.backup.upload.connection - if connection_settings.blank? - $progress.puts "skipped".yellow - return - end - - connection = ::Fog::Storage.new(connection_settings) - directory = connection.directories.get(remote_directory) - - if directory.files.create(key: tar_file, body: File.open(tar_file), public: false) - $progress.puts "done".green - else - puts "uploading backup to #{remote_directory} failed".red - abort 'Backup failed' - end - end - - def cleanup - $progress.print "Deleting tmp directories ... " - - backup_contents.each do |dir| - next unless File.exist?(File.join(Gitlab.config.backup.path, dir)) - - if FileUtils.rm_rf(File.join(Gitlab.config.backup.path, dir)) - $progress.puts "done".green - else - puts "deleting tmp directory '#{dir}' failed".red - abort 'Backup failed' - end - end - end - - def remove_old - # delete backups - $progress.print "Deleting old backups ... " - keep_time = Gitlab.config.backup.keep_time.to_i - - if keep_time > 0 - removed = 0 - - Dir.chdir(Gitlab.config.backup.path) do - file_list = Dir.glob('*_gitlab_backup.tar') - file_list.map! { |f| $1.to_i if f =~ /(\d+)_gitlab_backup.tar/ } - file_list.sort.each do |timestamp| - if Time.at(timestamp) < (Time.now - keep_time) - if Kernel.system(*%W(rm #{timestamp}_gitlab_backup.tar)) - removed += 1 - end - end - end - end - - $progress.puts "done. (#{removed} removed)".green - else - $progress.puts "skipping".yellow - end - end - - def unpack - Dir.chdir(Gitlab.config.backup.path) - - # check for existing backups in the backup dir - file_list = Dir.glob("*_gitlab_backup.tar").each.map { |f| f.split(/_/).first.to_i } - puts "no backups found" if file_list.count == 0 - - if file_list.count > 1 && ENV["BACKUP"].nil? - puts "Found more than one backup, please specify which one you want to restore:" - puts "rake gitlab:backup:restore BACKUP=timestamp_of_backup" - exit 1 - end - - tar_file = ENV["BACKUP"].nil? ? File.join("#{file_list.first}_gitlab_backup.tar") : File.join(ENV["BACKUP"] + "_gitlab_backup.tar") - - unless File.exists?(tar_file) - puts "The specified backup doesn't exist!" - exit 1 - end - - $progress.print "Unpacking backup ... " - - unless Kernel.system(*%W(tar -xf #{tar_file})) - puts "unpacking backup failed".red - exit 1 - else - $progress.puts "done".green - end - - ENV["VERSION"] = "#{settings[:db_version]}" if settings[:db_version].to_i > 0 - - # restoring mismatching backups can lead to unexpected problems - if settings[:gitlab_version] != Gitlab::VERSION - puts "GitLab version mismatch:".red - puts " Your current GitLab version (#{Gitlab::VERSION}) differs from the GitLab version in the backup!".red - puts " Please switch to the following version and try again:".red - puts " version: #{settings[:gitlab_version]}".red - puts - puts "Hint: git checkout v#{settings[:gitlab_version]}" - exit 1 - end - end - - def tar_version - tar_version, _ = Gitlab::Popen.popen(%W(tar --version)) - tar_version.force_encoding('locale').split("\n").first - end - - def skipped?(item) - settings[:skipped] && settings[:skipped].include?(item) - end - - private - - def backup_contents - folders_to_backup + ["backup_information.yml"] - end - - def folders_to_backup - folders = %w{repositories db uploads} - - if ENV["SKIP"] - return folders.reject{ |folder| ENV["SKIP"].include?(folder) } - end - - folders - end - - def settings - @settings ||= YAML.load_file("backup_information.yml") - end - end -end diff --git a/lib/backup/repository.rb b/lib/backup/repository.rb deleted file mode 100644 index dfb2da9f84e4b2598a3074fcf285e5242ebfe695..0000000000000000000000000000000000000000 --- a/lib/backup/repository.rb +++ /dev/null @@ -1,140 +0,0 @@ -require 'yaml' - -module Backup - class Repository - attr_reader :repos_path - - def dump - prepare - - Project.find_each(batch_size: 1000) do |project| - $progress.print " * #{project.path_with_namespace} ... " - - # Create namespace dir if missing - FileUtils.mkdir_p(File.join(backup_repos_path, project.namespace.path)) if project.namespace - - if project.empty_repo? - $progress.puts "[SKIPPED]".cyan - else - cmd = %W(tar -cf #{path_to_bundle(project)} -C #{path_to_repo(project)} .) - output, status = Gitlab::Popen.popen(cmd) - if status.zero? - $progress.puts "[DONE]".green - else - puts "[FAILED]".red - puts "failed: #{cmd.join(' ')}" - puts output - abort 'Backup failed' - end - end - - wiki = ProjectWiki.new(project) - - if File.exists?(path_to_repo(wiki)) - $progress.print " * #{wiki.path_with_namespace} ... " - if wiki.repository.empty? - $progress.puts " [SKIPPED]".cyan - else - cmd = %W(git --git-dir=#{path_to_repo(wiki)} bundle create #{path_to_bundle(wiki)} --all) - output, status = Gitlab::Popen.popen(cmd) - if status.zero? - $progress.puts " [DONE]".green - else - puts " [FAILED]".red - puts "failed: #{cmd.join(' ')}" - abort 'Backup failed' - end - end - end - end - end - - def restore - if File.exists?(repos_path) - # Move repos dir to 'repositories.old' dir - bk_repos_path = File.join(repos_path, '..', 'repositories.old.' + Time.now.to_i.to_s) - FileUtils.mv(repos_path, bk_repos_path) - end - - FileUtils.mkdir_p(repos_path) - - Project.find_each(batch_size: 1000) do |project| - $progress.print " * #{project.path_with_namespace} ... " - - project.namespace.ensure_dir_exist if project.namespace - - if File.exists?(path_to_bundle(project)) - FileUtils.mkdir_p(path_to_repo(project)) - cmd = %W(tar -xf #{path_to_bundle(project)} -C #{path_to_repo(project)}) - else - cmd = %W(git init --bare #{path_to_repo(project)}) - end - - if system(*cmd, silent) - $progress.puts "[DONE]".green - else - puts "[FAILED]".red - puts "failed: #{cmd.join(' ')}" - abort 'Restore failed' - end - - wiki = ProjectWiki.new(project) - - if File.exists?(path_to_bundle(wiki)) - $progress.print " * #{wiki.path_with_namespace} ... " - - # If a wiki bundle exists, first remove the empty repo - # that was initialized with ProjectWiki.new() and then - # try to restore with 'git clone --bare'. - FileUtils.rm_rf(path_to_repo(wiki)) - cmd = %W(git clone --bare #{path_to_bundle(wiki)} #{path_to_repo(wiki)}) - - if system(*cmd, silent) - $progress.puts " [DONE]".green - else - puts " [FAILED]".red - puts "failed: #{cmd.join(' ')}" - abort 'Restore failed' - end - end - end - - $progress.print 'Put GitLab hooks in repositories dirs'.yellow - cmd = "#{Gitlab.config.gitlab_shell.path}/bin/create-hooks" - if system(cmd) - $progress.puts " [DONE]".green - else - puts " [FAILED]".red - puts "failed: #{cmd}" - end - - end - - protected - - def path_to_repo(project) - project.repository.path_to_repo - end - - def path_to_bundle(project) - File.join(backup_repos_path, project.path_with_namespace + ".bundle") - end - - def repos_path - Gitlab.config.gitlab_shell.repos_path - end - - def backup_repos_path - File.join(Gitlab.config.backup.path, "repositories") - end - - def prepare - FileUtils.rm_rf(backup_repos_path) - FileUtils.mkdir_p(backup_repos_path) - end - - def silent - {err: '/dev/null', out: '/dev/null'} - end - end -end diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb deleted file mode 100644 index e50e1ff4f13add3afbc1515ed1ea3c05711440cb..0000000000000000000000000000000000000000 --- a/lib/backup/uploads.rb +++ /dev/null @@ -1,30 +0,0 @@ -module Backup - class Uploads - attr_reader :app_uploads_dir, :backup_uploads_dir, :backup_dir - - def initialize - @app_uploads_dir = File.realpath(Rails.root.join('public', 'uploads')) - @backup_dir = Gitlab.config.backup.path - @backup_uploads_dir = File.join(Gitlab.config.backup.path, 'uploads') - end - - # Copy uploads from public/uploads to backup/uploads - def dump - FileUtils.mkdir_p(backup_uploads_dir) - FileUtils.cp_r(app_uploads_dir, backup_dir) - end - - def restore - backup_existing_uploads_dir - - FileUtils.cp_r(backup_uploads_dir, app_uploads_dir) - end - - def backup_existing_uploads_dir - timestamped_uploads_path = File.join(app_uploads_dir, '..', "uploads.#{Time.now.to_i}") - if File.exists?(app_uploads_dir) - FileUtils.mv(app_uploads_dir, timestamped_uploads_path) - end - end - end -end diff --git a/lib/disable_email_interceptor.rb b/lib/disable_email_interceptor.rb deleted file mode 100644 index 1b80be112a436dfad99e68a4b6a8a1ab6d5373ba..0000000000000000000000000000000000000000 --- a/lib/disable_email_interceptor.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Read about interceptors in http://guides.rubyonrails.org/action_mailer_basics.html#intercepting-emails -class DisableEmailInterceptor - - def self.delivering_email(message) - message.perform_deliveries = false - Rails.logger.info "Emails disabled! Interceptor prevented sending mail #{message.subject}" - end -end diff --git a/lib/email_validator.rb b/lib/email_validator.rb deleted file mode 100644 index f509f0a584336fc0b3a1a5cccd36477eeb4c7fd4..0000000000000000000000000000000000000000 --- a/lib/email_validator.rb +++ /dev/null @@ -1,21 +0,0 @@ -# Based on https://github.com/balexand/email_validator -# -# Extended to use only strict mode with following allowed characters: -# ' - apostrophe -# -# See http://www.remote.org/jochen/mail/info/chars.html -# -class EmailValidator < ActiveModel::EachValidator - @@default_options = {} - - def self.default_options - @@default_options - end - - def validate_each(record, attribute, value) - options = @@default_options.merge(self.options) - unless value =~ /\A\s*([-a-z0-9+._']{1,64})@((?:[-a-z0-9]+\.)+[a-z]{2,})\s*\z/i - record.errors.add(attribute, options[:message] || :invalid) - end - end -end diff --git a/lib/event_filter.rb b/lib/event_filter.rb deleted file mode 100644 index 163937c02cfa75007e8e148ebec52c03915b21a3..0000000000000000000000000000000000000000 --- a/lib/event_filter.rb +++ /dev/null @@ -1,68 +0,0 @@ -class EventFilter - attr_accessor :params - - class << self - def default_filter - %w{ push issues merge_requests team} - end - - def push - 'push' - end - - def merged - 'merged' - end - - def comments - 'comments' - end - - def team - 'team' - end - end - - def initialize(params) - @params = if params - params.dup - else - []#EventFilter.default_filter - end - end - - def apply_filter(events) - return events unless params.present? - - filter = params.dup - - actions = [] - actions << Event::PUSHED if filter.include? 'push' - actions << Event::MERGED if filter.include? 'merged' - - if filter.include? 'team' - actions << Event::JOINED - actions << Event::LEFT - end - - actions << Event::COMMENTED if filter.include? 'comments' - - events = events.where(action: actions) - end - - def options(key) - filter = params.dup - - if filter.include? key - filter.delete key - else - filter << key - end - - filter - end - - def active?(key) - params.include? key - end -end diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb deleted file mode 100644 index 6e4ed01e079c2dde1f15c7431a4d415b73b180cb..0000000000000000000000000000000000000000 --- a/lib/extracts_path.rb +++ /dev/null @@ -1,123 +0,0 @@ -# Module providing methods for dealing with separating a tree-ish string and a -# file path string when combined in a request parameter -module ExtractsPath - # Raised when given an invalid file path - class InvalidPathError < StandardError; end - - # Given a string containing both a Git tree-ish, such as a branch or tag, and - # a filesystem path joined by forward slashes, attempts to separate the two. - # - # Expects a @project instance variable to contain the active project. This is - # used to check the input against a list of valid repository refs. - # - # Examples - # - # # No @project available - # extract_ref('master') - # # => ['', ''] - # - # extract_ref('master') - # # => ['master', ''] - # - # extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG") - # # => ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG'] - # - # extract_ref("v2.0.0/README.md") - # # => ['v2.0.0', 'README.md'] - # - # extract_ref('master/app/models/project.rb') - # # => ['master', 'app/models/project.rb'] - # - # extract_ref('issues/1234/app/models/project.rb') - # # => ['issues/1234', 'app/models/project.rb'] - # - # # Given an invalid branch, we fall back to just splitting on the first slash - # extract_ref('non/existent/branch/README.md') - # # => ['non', 'existent/branch/README.md'] - # - # Returns an Array where the first value is the tree-ish and the second is the - # path - def extract_ref(id) - pair = ['', ''] - - return pair unless @project - - if id.match(/^([[:alnum:]]{40})(.+)/) - # If the ref appears to be a SHA, we're done, just split the string - pair = $~.captures - else - # Otherwise, attempt to detect the ref using a list of the project's - # branches and tags - - # Append a trailing slash if we only get a ref and no file path - id += '/' unless id.ends_with?('/') - - valid_refs = @project.repository.ref_names - valid_refs.select! { |v| id.start_with?("#{v}/") } - - if valid_refs.length != 1 - # No exact ref match, so just try our best - pair = id.match(/([^\/]+)(.*)/).captures - else - # Partition the string into the ref and the path, ignoring the empty first value - pair = id.partition(valid_refs.first)[1..-1] - end - end - - # Remove ending slashes from path - pair[1].gsub!(/^\/|\/$/, '') - - pair - end - - # Assigns common instance variables for views working with Git tree-ish objects - # - # Assignments are: - # - # - @id - A string representing the joined ref and path - # - @ref - A string representing the ref (e.g., the branch, tag, or commit SHA) - # - @path - A string representing the filesystem path - # - @commit - A Commit representing the commit from the given ref - # - # If the :id parameter appears to be requesting a specific response format, - # that will be handled as well. - # - # Automatically renders `not_found!` if a valid tree path could not be - # resolved (e.g., when a user inserts an invalid path or ref). - def assign_ref_vars - # assign allowed options - allowed_options = ["filter_ref", "extended_sha1"] - @options = params.select {|key, value| allowed_options.include?(key) && !value.blank? } - @options = HashWithIndifferentAccess.new(@options) - - @id = get_id - @ref, @path = extract_ref(@id) - @repo = @project.repository - if @options[:extended_sha1].blank? - @commit = @repo.commit(@ref) - else - @commit = @repo.commit(@options[:extended_sha1]) - end - - raise InvalidPathError unless @commit - - @hex_path = Digest::SHA1.hexdigest(@path) - @logs_path = logs_file_namespace_project_ref_path(@project.namespace, - @project, @ref, @path) - - rescue RuntimeError, NoMethodError, InvalidPathError - not_found! - end - - def tree - @tree ||= @repo.tree(@commit.id, @path) - end - - private - - def get_id - id = params[:id] || params[:ref] - id += "/" + params[:path] unless params[:path].blank? - id - end -end diff --git a/lib/file_size_validator.rb b/lib/file_size_validator.rb deleted file mode 100644 index 2eae55e534b4e6d9ed0a5b1dcb44d13bb959772d..0000000000000000000000000000000000000000 --- a/lib/file_size_validator.rb +++ /dev/null @@ -1,73 +0,0 @@ -class FileSizeValidator < ActiveModel::EachValidator - MESSAGES = { is: :wrong_size, minimum: :size_too_small, maximum: :size_too_big }.freeze - CHECKS = { is: :==, minimum: :>=, maximum: :<= }.freeze - - DEFAULT_TOKENIZER = lambda { |value| value.split(//) } - RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long] - - def initialize(options) - if range = (options.delete(:in) || options.delete(:within)) - raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range) - options[:minimum], options[:maximum] = range.begin, range.end - options[:maximum] -= 1 if range.exclude_end? - end - - super - end - - def check_validity! - keys = CHECKS.keys & options.keys - - if keys.empty? - raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.' - end - - keys.each do |key| - value = options[key] - - unless (value.is_a?(Integer) && value >= 0) || value.is_a?(Symbol) - raise ArgumentError, ":#{key} must be a nonnegative Integer or symbol" - end - end - end - - def validate_each(record, attribute, value) - raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base - - value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String) - - CHECKS.each do |key, validity_check| - next unless check_value = options[key] - - check_value = - case check_value - when Integer - check_value - when Symbol - record.send(check_value) - end - - value ||= [] if key == :maximum - - value_size = value.size - next if value_size.send(validity_check, check_value) - - errors_options = options.except(*RESERVED_OPTIONS) - errors_options[:file_size] = help.number_to_human_size check_value - - default_message = options[MESSAGES[key]] - errors_options[:message] ||= default_message if default_message - - record.errors.add(attribute, MESSAGES[key], errors_options) - end - end - - def help - Helper.instance - end - - class Helper - include Singleton - include ActionView::Helpers::NumberHelper - end -end diff --git a/lib/gitlab.rb b/lib/gitlab.rb deleted file mode 100644 index 5fc1862c3e931f3ec7ab8907c0ce25f192c67a52..0000000000000000000000000000000000000000 --- a/lib/gitlab.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'gitlab/git' - -module Gitlab - autoload :Satellite, 'gitlab/satellite/satellite' -end diff --git a/lib/gitlab/access.rb b/lib/gitlab/access.rb deleted file mode 100644 index 424541b4a04c259b5e5de0761f7f7d03fec61d28..0000000000000000000000000000000000000000 --- a/lib/gitlab/access.rb +++ /dev/null @@ -1,73 +0,0 @@ -# Gitlab::Access module -# -# Define allowed roles that can be used -# in GitLab code to determine authorization level -# -module Gitlab - module Access - GUEST = 10 - REPORTER = 20 - DEVELOPER = 30 - MASTER = 40 - OWNER = 50 - - # Branch protection settings - PROTECTION_NONE = 0 - PROTECTION_DEV_CAN_PUSH = 1 - PROTECTION_FULL = 2 - - class << self - def values - options.values - end - - def all_values - options_with_owner.values - end - - def options - { - "Guest" => GUEST, - "Reporter" => REPORTER, - "Developer" => DEVELOPER, - "Master" => MASTER, - } - end - - def options_with_owner - options.merge( - "Owner" => OWNER - ) - end - - def sym_options - { - guest: GUEST, - reporter: REPORTER, - developer: DEVELOPER, - master: MASTER, - } - end - - def protection_options - { - "Not protected, developers and masters can (force) push and delete the branch" => PROTECTION_NONE, - "Partially protected, developers can also push but prevent all force pushes and deletion" => PROTECTION_DEV_CAN_PUSH, - "Fully protected, only masters can push and prevent all force pushes and deletion" => PROTECTION_FULL, - } - end - - def protection_values - protection_options.values - end - end - - def human_access - Gitlab::Access.options_with_owner.key(access_field) - end - - def owner? - access_field == OWNER - end - end -end diff --git a/lib/gitlab/app_logger.rb b/lib/gitlab/app_logger.rb deleted file mode 100644 index dddcb2538f915a8eab9c2801522b62c511aa2c14..0000000000000000000000000000000000000000 --- a/lib/gitlab/app_logger.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Gitlab - class AppLogger < Gitlab::Logger - def self.file_name_noext - 'application' - end - - def format_message(severity, timestamp, progname, msg) - "#{timestamp.to_s(:long)}: #{msg}\n" - end - end -end diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb deleted file mode 100644 index 30509528b8b6ba5a44d32b47e382d8906b61f9d8..0000000000000000000000000000000000000000 --- a/lib/gitlab/auth.rb +++ /dev/null @@ -1,18 +0,0 @@ -module Gitlab - class Auth - def find(login, password) - user = User.by_login(login) - - # If no user is found, or it's an LDAP server, try LDAP. - # LDAP users are only authenticated via LDAP - if user.nil? || user.ldap_user? - # Second chance - try LDAP authentication - return nil unless Gitlab::LDAP::Config.enabled? - - Gitlab::LDAP::Authentication.login(login, password) - else - user if user.valid_password?(password) - end - end - end -end diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb deleted file mode 100644 index 050b5ba29dd5e31b5b052680fef474966f2d5778..0000000000000000000000000000000000000000 --- a/lib/gitlab/backend/grack_auth.rb +++ /dev/null @@ -1,182 +0,0 @@ -require_relative 'rack_attack_helpers' -require_relative 'shell_env' - -module Grack - class Auth < Rack::Auth::Basic - - attr_accessor :user, :project, :env - - def call(env) - @env = env - @request = Rack::Request.new(env) - @auth = Request.new(env) - - @gitlab_ci = false - - # Need this patch due to the rails mount - # Need this if under RELATIVE_URL_ROOT - unless Gitlab.config.gitlab.relative_url_root.empty? - # If website is mounted using relative_url_root need to remove it first - @env['PATH_INFO'] = @request.path.sub(Gitlab.config.gitlab.relative_url_root,'') - else - @env['PATH_INFO'] = @request.path - end - - @env['SCRIPT_NAME'] = "" - - auth! - - if project && authorized_request? - @app.call(env) - elsif @user.nil? && !@gitlab_ci - unauthorized - else - render_not_found - end - end - - private - - def auth! - return unless @auth.provided? - - return bad_request unless @auth.basic? - - # Authentication with username and password - login, password = @auth.credentials - - # Allow authentication for GitLab CI service - # if valid token passed - if gitlab_ci_request?(login, password) - @gitlab_ci = true - return - end - - @user = authenticate_user(login, password) - - if @user - Gitlab::ShellEnv.set_env(@user) - @env['REMOTE_USER'] = @auth.username - end - end - - def gitlab_ci_request?(login, password) - if login == "gitlab-ci-token" && project && project.gitlab_ci? - token = project.gitlab_ci_service.token - - if token.present? && token == password && git_cmd == 'git-upload-pack' - return true - end - end - - false - end - - def oauth_access_token_check(login, password) - if login == "oauth2" && git_cmd == 'git-upload-pack' && password.present? - token = Doorkeeper::AccessToken.by_token(password) - token && token.accessible? && User.find_by(id: token.resource_owner_id) - end - end - - def authenticate_user(login, password) - user = Gitlab::Auth.new.find(login, password) - - unless user - user = oauth_access_token_check(login, password) - end - - # If the user authenticated successfully, we reset the auth failure count - # from Rack::Attack for that IP. A client may attempt to authenticate - # with a username and blank password first, and only after it receives - # a 401 error does it present a password. Resetting the count prevents - # false positives from occurring. - # - # Otherwise, we let Rack::Attack know there was a failed authentication - # attempt from this IP. This information is stored in the Rails cache - # (Redis) and will be used by the Rack::Attack middleware to decide - # whether to block requests from this IP. - config = Gitlab.config.rack_attack.git_basic_auth - - if config.enabled - if user - # A successful login will reset the auth failure count from this IP - Rack::Attack::Allow2Ban.reset(@request.ip, config) - else - banned = Rack::Attack::Allow2Ban.filter(@request.ip, config) do - # Unless the IP is whitelisted, return true so that Allow2Ban - # increments the counter (stored in Rails.cache) for the IP - if config.ip_whitelist.include?(@request.ip) - false - else - true - end - end - - if banned - Rails.logger.info "IP #{@request.ip} failed to login " \ - "as #{login} but has been temporarily banned from Git auth" - end - end - end - - user - end - - def authorized_request? - return true if @gitlab_ci - - case git_cmd - when *Gitlab::GitAccess::DOWNLOAD_COMMANDS - if user - Gitlab::GitAccess.new(user, project).download_access_check.allowed? - elsif project.public? - # Allow clone/fetch for public projects - true - else - false - end - when *Gitlab::GitAccess::PUSH_COMMANDS - if user - # Skip user authorization on upload request. - # It will be done by the pre-receive hook in the repository. - true - else - false - end - else - false - end - end - - def git_cmd - if @request.get? - @request.params['service'] - elsif @request.post? - File.basename(@request.path) - else - nil - end - end - - def project - return @project if defined?(@project) - - @project = project_by_path(@request.path_info) - end - - def project_by_path(path) - if m = /^([\w\.\/-]+)\.git/.match(path).to_a - path_with_namespace = m.last - path_with_namespace.gsub!(/\.wiki$/, '') - - path_with_namespace[0] = '' if path_with_namespace.start_with?('/') - Project.find_with_namespace(path_with_namespace) - end - end - - def render_not_found - [404, { "Content-Type" => "text/plain" }, ["Not Found"]] - end - end -end diff --git a/lib/gitlab/backend/rack_attack_helpers.rb b/lib/gitlab/backend/rack_attack_helpers.rb deleted file mode 100644 index 8538f3f6ecab3eaf0069455447ba47c84fa9693b..0000000000000000000000000000000000000000 --- a/lib/gitlab/backend/rack_attack_helpers.rb +++ /dev/null @@ -1,31 +0,0 @@ -# rack-attack v4.2.0 doesn't yet support clearing of keys. -# Taken from https://github.com/kickstarter/rack-attack/issues/113 -class Rack::Attack::Allow2Ban - def self.reset(discriminator, options) - findtime = options[:findtime] or raise ArgumentError, "Must pass findtime option" - - cache.reset_count("#{key_prefix}:count:#{discriminator}", findtime) - cache.delete("#{key_prefix}:ban:#{discriminator}") - end -end - -class Rack::Attack::Cache - def reset_count(unprefixed_key, period) - epoch_time = Time.now.to_i - # Add 1 to expires_in to avoid timing error: http://git.io/i1PHXA - expires_in = period - (epoch_time % period) + 1 - key = "#{(epoch_time / period).to_i}:#{unprefixed_key}" - delete(key) - end - - def delete(unprefixed_key) - store.delete("#{prefix}:#{unprefixed_key}") - end -end - -class Rack::Attack::StoreProxy::RedisStoreProxy - def delete(key, options={}) - self.del(key) - rescue Redis::BaseError - end -end diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb deleted file mode 100644 index 530f9d93de4719479e1f6c6ebb835dbf584ef51e..0000000000000000000000000000000000000000 --- a/lib/gitlab/backend/shell.rb +++ /dev/null @@ -1,279 +0,0 @@ -module Gitlab - class Shell - class AccessDenied < StandardError; end - - class KeyAdder < Struct.new(:io) - def add_key(id, key) - io.puts("#{id}\t#{key.strip}") - end - end - - class << self - def version_required - @version_required ||= File.read(Rails.root. - join('GITLAB_SHELL_VERSION')).strip - end - end - - # Init new repository - # - # name - project path with namespace - # - # Ex. - # add_repository("gitlab/gitlab-ci") - # - def add_repository(name) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, - 'add-project', "#{name}.git"]) - end - - # Import repository - # - # name - project path with namespace - # - # Ex. - # import_repository("gitlab/gitlab-ci", "https://github.com/randx/six.git") - # - def import_repository(name, url) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'import-project', - "#{name}.git", url, '240']) - end - - # Move repository - # - # path - project path with namespace - # new_path - new project path with namespace - # - # Ex. - # mv_repository("gitlab/gitlab-ci", "randx/gitlab-ci-new.git") - # - def mv_repository(path, new_path) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'mv-project', - "#{path}.git", "#{new_path}.git"]) - end - - # Update HEAD for repository - # - # path - project path with namespace - # branch - repository branch name - # - # Ex. - # update_repository_head("gitlab/gitlab-ci", "3-1-stable") - # - def update_repository_head(path, branch) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'update-head', - "#{path}.git", branch]) - end - - # Fork repository to new namespace - # - # path - project path with namespace - # fork_namespace - namespace for forked project - # - # Ex. - # fork_repository("gitlab/gitlab-ci", "randx") - # - def fork_repository(path, fork_namespace) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'fork-project', - "#{path}.git", fork_namespace]) - end - - # Remove repository from file system - # - # name - project path with namespace - # - # Ex. - # remove_repository("gitlab/gitlab-ci") - # - def remove_repository(name) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, - 'rm-project', "#{name}.git"]) - end - - # Add repository branch from passed ref - # - # path - project path with namespace - # branch_name - new branch name - # ref - HEAD for new branch - # - # Ex. - # add_branch("gitlab/gitlab-ci", "4-0-stable", "master") - # - def add_branch(path, branch_name, ref) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'create-branch', - "#{path}.git", branch_name, ref]) - end - - # Remove repository branch - # - # path - project path with namespace - # branch_name - branch name to remove - # - # Ex. - # rm_branch("gitlab/gitlab-ci", "4-0-stable") - # - def rm_branch(path, branch_name) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'rm-branch', - "#{path}.git", branch_name]) - end - - # Add repository tag from passed ref - # - # path - project path with namespace - # tag_name - new tag name - # ref - HEAD for new tag - # message - optional message for tag (annotated tag) - # - # Ex. - # add_tag("gitlab/gitlab-ci", "v4.0", "master") - # add_tag("gitlab/gitlab-ci", "v4.0", "master", "message") - # - def add_tag(path, tag_name, ref, message = nil) - cmd = %W(#{gitlab_shell_path}/bin/gitlab-projects create-tag #{path}.git - #{tag_name} #{ref}) - cmd << message unless message.nil? || message.empty? - Gitlab::Utils.system_silent(cmd) - end - - # Remove repository tag - # - # path - project path with namespace - # tag_name - tag name to remove - # - # Ex. - # rm_tag("gitlab/gitlab-ci", "v4.0") - # - def rm_tag(path, tag_name) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'rm-tag', - "#{path}.git", tag_name]) - end - - # Add new key to gitlab-shell - # - # Ex. - # add_key("key-42", "sha-rsa ...") - # - def add_key(key_id, key_content) - Gitlab::Utils.system_silent([gitlab_shell_keys_path, - 'add-key', key_id, key_content]) - end - - # Batch-add keys to authorized_keys - # - # Ex. - # batch_add_keys { |adder| adder.add_key("key-42", "sha-rsa ...") } - def batch_add_keys(&block) - IO.popen(%W(#{gitlab_shell_path}/bin/gitlab-keys batch-add-keys), 'w') do |io| - block.call(KeyAdder.new(io)) - end - end - - # Remove ssh key from gitlab shell - # - # Ex. - # remove_key("key-342", "sha-rsa ...") - # - def remove_key(key_id, key_content) - Gitlab::Utils.system_silent([gitlab_shell_keys_path, - 'rm-key', key_id, key_content]) - end - - # Remove all ssh keys from gitlab shell - # - # Ex. - # remove_all_keys - # - def remove_all_keys - Gitlab::Utils.system_silent([gitlab_shell_keys_path, 'clear']) - end - - # Add empty directory for storing repositories - # - # Ex. - # add_namespace("gitlab") - # - def add_namespace(name) - FileUtils.mkdir(full_path(name), mode: 0770) unless exists?(name) - end - - # Remove directory from repositories storage - # Every repository inside this directory will be removed too - # - # Ex. - # rm_namespace("gitlab") - # - def rm_namespace(name) - FileUtils.rm_r(full_path(name), force: true) - end - - # Move namespace directory inside repositories storage - # - # Ex. - # mv_namespace("gitlab", "gitlabhq") - # - def mv_namespace(old_name, new_name) - return false if exists?(new_name) || !exists?(old_name) - - FileUtils.mv(full_path(old_name), full_path(new_name)) - end - - # Remove GitLab Satellites for provided path (namespace or repo dir) - # - # Ex. - # rm_satellites("gitlab") - # - # rm_satellites("gitlab/gitlab-ci.git") - # - def rm_satellites(path) - raise ArgumentError.new("Path can't be blank") if path.blank? - - satellites_path = File.join(Gitlab.config.satellites.path, path) - FileUtils.rm_r(satellites_path, force: true) - end - - def url_to_repo(path) - Gitlab.config.gitlab_shell.ssh_path_prefix + "#{path}.git" - end - - # Return GitLab shell version - def version - gitlab_shell_version_file = "#{gitlab_shell_path}/VERSION" - - if File.readable?(gitlab_shell_version_file) - File.read(gitlab_shell_version_file).chomp - end - end - - protected - - def gitlab_shell_path - Gitlab.config.gitlab_shell.path - end - - def gitlab_shell_user_home - File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}") - end - - def repos_path - Gitlab.config.gitlab_shell.repos_path - end - - def full_path(dir_name) - raise ArgumentError.new("Directory name can't be blank") if dir_name.blank? - - File.join(repos_path, dir_name) - end - - def exists?(dir_name) - File.exists?(full_path(dir_name)) - end - - def gitlab_shell_projects_path - File.join(gitlab_shell_path, 'bin', 'gitlab-projects') - end - - def gitlab_shell_keys_path - File.join(gitlab_shell_path, 'bin', 'gitlab-keys') - end - end -end diff --git a/lib/gitlab/backend/shell_adapter.rb b/lib/gitlab/backend/shell_adapter.rb deleted file mode 100644 index fbe2a7a0d721ad474e85c72090c8b6431ce386da..0000000000000000000000000000000000000000 --- a/lib/gitlab/backend/shell_adapter.rb +++ /dev/null @@ -1,11 +0,0 @@ -# == GitLab Shell mixin -# -# Provide a shortcut to Gitlab::Shell instance by gitlab_shell -# -module Gitlab - module ShellAdapter - def gitlab_shell - Gitlab::Shell.new - end - end -end diff --git a/lib/gitlab/backend/shell_env.rb b/lib/gitlab/backend/shell_env.rb deleted file mode 100644 index 044afb27f3fad36c760e8ba0dabd96a53db11809..0000000000000000000000000000000000000000 --- a/lib/gitlab/backend/shell_env.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Gitlab - # This module provide 2 methods - # to set specific ENV variables for GitLab Shell - module ShellEnv - extend self - - def set_env(user) - # Set GL_ID env variable - ENV['GL_ID'] = "user-#{user.id}" - end - - def reset_env - # Reset GL_ID env variable - ENV['GL_ID'] = nil - end - end -end diff --git a/lib/gitlab/bitbucket_import.rb b/lib/gitlab/bitbucket_import.rb deleted file mode 100644 index 7298152e7e98515524815f239706ca9abf9f558d..0000000000000000000000000000000000000000 --- a/lib/gitlab/bitbucket_import.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Gitlab - module BitbucketImport - mattr_accessor :public_key - @public_key = nil - end -end diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb deleted file mode 100644 index 5b1952b9675f126671b0d85db88e149e13b52f54..0000000000000000000000000000000000000000 --- a/lib/gitlab/bitbucket_import/client.rb +++ /dev/null @@ -1,99 +0,0 @@ -module Gitlab - module BitbucketImport - class Client - attr_reader :consumer, :api - - def initialize(access_token = nil, access_token_secret = nil) - @consumer = ::OAuth::Consumer.new( - config.app_id, - config.app_secret, - bitbucket_options - ) - - if access_token && access_token_secret - @api = ::OAuth::AccessToken.new(@consumer, access_token, access_token_secret) - end - end - - def request_token(redirect_uri) - request_token = consumer.get_request_token(oauth_callback: redirect_uri) - - { - oauth_token: request_token.token, - oauth_token_secret: request_token.secret, - oauth_callback_confirmed: request_token.callback_confirmed?.to_s - } - end - - def authorize_url(request_token, redirect_uri) - request_token = ::OAuth::RequestToken.from_hash(consumer, request_token) if request_token.is_a?(Hash) - - if request_token.callback_confirmed? - request_token.authorize_url - else - request_token.authorize_url(oauth_callback: redirect_uri) - end - end - - def get_token(request_token, oauth_verifier, redirect_uri) - request_token = ::OAuth::RequestToken.from_hash(consumer, request_token) if request_token.is_a?(Hash) - - if request_token.callback_confirmed? - request_token.get_access_token(oauth_verifier: oauth_verifier) - else - request_token.get_access_token(oauth_callback: redirect_uri) - end - end - - def user - JSON.parse(api.get("/api/1.0/user").body) - end - - def issues(project_identifier) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/issues").body) - end - - def issue_comments(project_identifier, issue_id) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/issues/#{issue_id}/comments").body) - end - - def project(project_identifier) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}").body) - end - - def find_deploy_key(project_identifier, key) - JSON.parse(api.get("/api/1.0/repositories/#{project_identifier}/deploy-keys").body).find do |deploy_key| - deploy_key["key"].chomp == key.chomp - end - end - - def add_deploy_key(project_identifier, key) - deploy_key = find_deploy_key(project_identifier, key) - return if deploy_key - - JSON.parse(api.post("/api/1.0/repositories/#{project_identifier}/deploy-keys", key: key, label: "GitLab import key").body) - end - - def delete_deploy_key(project_identifier, key) - deploy_key = find_deploy_key(project_identifier, key) - return unless deploy_key - - api.delete("/api/1.0/repositories/#{project_identifier}/deploy-keys/#{deploy_key["pk"]}").code == "204" - end - - def projects - JSON.parse(api.get("/api/1.0/user/repositories").body).select { |repo| repo["scm"] == "git" } - end - - private - - def config - Gitlab.config.omniauth.providers.find { |provider| provider.name == "bitbucket"} - end - - def bitbucket_options - OmniAuth::Strategies::Bitbucket.default_options[:client_options].symbolize_keys - end - end - end -end diff --git a/lib/gitlab/bitbucket_import/importer.rb b/lib/gitlab/bitbucket_import/importer.rb deleted file mode 100644 index 42c93707caa69cba20af39ff39af6112b90bdbc1..0000000000000000000000000000000000000000 --- a/lib/gitlab/bitbucket_import/importer.rb +++ /dev/null @@ -1,52 +0,0 @@ -module Gitlab - module BitbucketImport - class Importer - attr_reader :project, :client - - def initialize(project) - @project = project - @client = Client.new(project.creator.bitbucket_access_token, project.creator.bitbucket_access_token_secret) - @formatter = Gitlab::ImportFormatter.new - end - - def execute - project_identifier = project.import_source - - return true unless client.project(project_identifier)["has_issues"] - - #Issues && Comments - issues = client.issues(project_identifier) - - issues["issues"].each do |issue| - body = @formatter.author_line(issue["reported_by"]["username"], issue["content"]) - - comments = client.issue_comments(project_identifier, issue["local_id"]) - - if comments.any? - body += @formatter.comments_header - end - - comments.each do |comment| - body += @formatter.comment(comment["author_info"]["username"], comment["utc_created_on"], comment["content"]) - end - - project.issues.create!( - description: body, - title: issue["title"], - state: %w(resolved invalid duplicate wontfix).include?(issue["status"]) ? 'closed' : 'opened', - author_id: gl_user_id(project, issue["reported_by"]["username"]) - ) - end - - true - end - - private - - def gl_user_id(project, bitbucket_id) - user = User.joins(:identities).find_by("identities.extern_uid = ? AND identities.provider = 'bitbucket'", bitbucket_id.to_s) - (user && user.id) || project.creator_id - end - end - end -end diff --git a/lib/gitlab/bitbucket_import/key_adder.rb b/lib/gitlab/bitbucket_import/key_adder.rb deleted file mode 100644 index 9931aa7e029996fbb95f63ac13f11d94db79569c..0000000000000000000000000000000000000000 --- a/lib/gitlab/bitbucket_import/key_adder.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Gitlab - module BitbucketImport - class KeyAdder - attr_reader :repo, :current_user, :client - - def initialize(repo, current_user) - @repo, @current_user = repo, current_user - @client = Client.new(current_user.bitbucket_access_token, current_user.bitbucket_access_token_secret) - end - - def execute - return false unless BitbucketImport.public_key.present? - - project_identifier = "#{repo["owner"]}/#{repo["slug"]}" - client.add_deploy_key(project_identifier, BitbucketImport.public_key) - - true - rescue - false - end - end - end -end diff --git a/lib/gitlab/bitbucket_import/key_deleter.rb b/lib/gitlab/bitbucket_import/key_deleter.rb deleted file mode 100644 index 1a24a86fc37c0f00d8900633e11fd0efa261566c..0000000000000000000000000000000000000000 --- a/lib/gitlab/bitbucket_import/key_deleter.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Gitlab - module BitbucketImport - class KeyDeleter - attr_reader :project, :current_user, :client - - def initialize(project) - @project = project - @current_user = project.creator - @client = Client.new(current_user.bitbucket_access_token, current_user.bitbucket_access_token_secret) - end - - def execute - return false unless BitbucketImport.public_key.present? - - client.delete_deploy_key(project.import_source, BitbucketImport.public_key) - - true - rescue - false - end - end - end -end diff --git a/lib/gitlab/bitbucket_import/project_creator.rb b/lib/gitlab/bitbucket_import/project_creator.rb deleted file mode 100644 index 54420e62c9091a1df425d2f60a7d61b8ae85b48c..0000000000000000000000000000000000000000 --- a/lib/gitlab/bitbucket_import/project_creator.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Gitlab - module BitbucketImport - class ProjectCreator - attr_reader :repo, :namespace, :current_user - - def initialize(repo, namespace, current_user) - @repo = repo - @namespace = namespace - @current_user = current_user - end - - def execute - ::Projects::CreateService.new(current_user, - name: repo["name"], - path: repo["slug"], - description: repo["description"], - namespace_id: namespace.id, - visibility_level: repo["is_private"] ? Gitlab::VisibilityLevel::PRIVATE : Gitlab::VisibilityLevel::PUBLIC, - import_type: "bitbucket", - import_source: "#{repo["owner"]}/#{repo["slug"]}", - import_url: "ssh://git@bitbucket.org/#{repo["owner"]}/#{repo["slug"]}.git" - ).execute - end - end - end -end diff --git a/lib/gitlab/blacklist.rb b/lib/gitlab/blacklist.rb deleted file mode 100644 index 43145e0ee1b7f2a96b45840678dc1485a47acd1b..0000000000000000000000000000000000000000 --- a/lib/gitlab/blacklist.rb +++ /dev/null @@ -1,34 +0,0 @@ -module Gitlab - module Blacklist - extend self - - def path - %w( - admin - dashboard - files - groups - help - profile - projects - search - public - assets - u - s - teams - merge_requests - issues - users - snippets - services - repository - hooks - notes - unsubscribes - all - ci - ) - end - end -end diff --git a/lib/gitlab/closing_issue_extractor.rb b/lib/gitlab/closing_issue_extractor.rb deleted file mode 100644 index ab184d95c052587c3cf848245386335652fe5202..0000000000000000000000000000000000000000 --- a/lib/gitlab/closing_issue_extractor.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Gitlab - class ClosingIssueExtractor - ISSUE_CLOSING_REGEX = Regexp.new(Gitlab.config.gitlab.issue_closing_pattern) - - def initialize(project, current_user = nil) - @extractor = Gitlab::ReferenceExtractor.new(project, current_user) - end - - def closed_by_message(message) - return [] if message.nil? - - closing_statements = message.scan(ISSUE_CLOSING_REGEX). - map { |ref| ref[0] }.join(" ") - - @extractor.analyze(closing_statements) - - @extractor.issues - end - end -end diff --git a/lib/gitlab/compare_result.rb b/lib/gitlab/compare_result.rb deleted file mode 100644 index d72391dade5f025022bcc4974ca0e1ec8db2751d..0000000000000000000000000000000000000000 --- a/lib/gitlab/compare_result.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Gitlab - class CompareResult - attr_reader :commits, :diffs - - def initialize(compare) - @commits, @diffs = compare.commits, compare.diffs - end - end -end diff --git a/lib/gitlab/config_helper.rb b/lib/gitlab/config_helper.rb deleted file mode 100644 index 41880069e4cfc4e3fbcf2b4f69cc816122b3394a..0000000000000000000000000000000000000000 --- a/lib/gitlab/config_helper.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Gitlab::ConfigHelper - def gitlab_config_features - Gitlab.config.gitlab.default_projects_features - end - - def gitlab_config - Gitlab.config.gitlab - end -end diff --git a/lib/gitlab/contributions_calendar.rb b/lib/gitlab/contributions_calendar.rb deleted file mode 100644 index 3fd0823df063662b5f05ead5446e6c4897200ba5..0000000000000000000000000000000000000000 --- a/lib/gitlab/contributions_calendar.rb +++ /dev/null @@ -1,56 +0,0 @@ -module Gitlab - class ContributionsCalendar - attr_reader :timestamps, :projects, :user - - def initialize(projects, user) - @projects = projects - @user = user - end - - def timestamps - return @timestamps if @timestamps.present? - - @timestamps = {} - date_from = 1.year.ago - date_to = Date.today - - events = Event.reorder(nil).contributions.where(author_id: user.id). - where("created_at > ?", date_from).where(project_id: projects). - group('date(created_at)'). - select('date(created_at), count(id) as total_amount'). - map(&:attributes) - - dates = (1.year.ago.to_date..(Date.today + 1.day)).to_a - - dates.each do |date| - date_id = date.to_time.to_i.to_s - @timestamps[date_id] = 0 - day_events = events.find { |day_events| day_events["date"] == date } - - if day_events - @timestamps[date_id] = day_events["total_amount"] - end - end - - @timestamps - end - - def events_by_date(date) - events = Event.contributions.where(author_id: user.id). - where("created_at > ? AND created_at < ?", date.beginning_of_day, date.end_of_day). - where(project_id: projects) - - events.select do |event| - event.push? || event.issue? || event.merge_request? - end - end - - def starting_year - (Time.now - 1.year).strftime("%Y") - end - - def starting_month - Date.today.strftime("%m").to_i - end - end -end diff --git a/lib/gitlab/contributor.rb b/lib/gitlab/contributor.rb deleted file mode 100644 index c41e92b620ff4e7713d2ea4ce54feabc5a4365df..0000000000000000000000000000000000000000 --- a/lib/gitlab/contributor.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Gitlab - class Contributor - attr_accessor :email, :name, :commits, :additions, :deletions - - def initialize - @commits, @additions, @deletions = 0, 0, 0 - end - end -end diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb deleted file mode 100644 index d8f696d247b4c8130bc50837154ae5b141cc6fea..0000000000000000000000000000000000000000 --- a/lib/gitlab/current_settings.rb +++ /dev/null @@ -1,28 +0,0 @@ -module Gitlab - module CurrentSettings - def current_application_settings - key = :current_application_settings - - RequestStore.store[key] ||= begin - if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('application_settings') - ApplicationSetting.current || ApplicationSetting.create_from_defaults - else - fake_application_settings - end - end - end - - def fake_application_settings - OpenStruct.new( - default_projects_limit: Settings.gitlab['default_projects_limit'], - default_branch_protection: Settings.gitlab['default_branch_protection'], - signup_enabled: Settings.gitlab['signup_enabled'], - signin_enabled: Settings.gitlab['signin_enabled'], - gravatar_enabled: Settings.gravatar['enabled'], - sign_in_text: Settings.extra['sign_in_text'], - restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'], - max_attachment_size: Settings.gitlab['max_attachment_size'] - ) - end - end -end diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb deleted file mode 100644 index 4daf65331e8738d961ffdcfd96154e180431b74f..0000000000000000000000000000000000000000 --- a/lib/gitlab/diff/file.rb +++ /dev/null @@ -1,49 +0,0 @@ -module Gitlab - module Diff - class File - attr_reader :diff - - delegate :new_file, :deleted_file, :renamed_file, - :old_path, :new_path, to: :diff, prefix: false - - def initialize(diff) - @diff = diff - end - - # Array of Gitlab::DIff::Line objects - def diff_lines - @lines ||= parser.parse(raw_diff.lines) - end - - def mode_changed? - !!(diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode) - end - - def parser - Gitlab::Diff::Parser.new - end - - def raw_diff - diff.diff.to_s - end - - def next_line(index) - diff_lines[index + 1] - end - - def prev_line(index) - if index > 0 - diff_lines[index - 1] - end - end - - def file_path - if diff.new_path.present? - diff.new_path - elsif diff.old_path.present? - diff.old_path - end - end - end - end -end diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb deleted file mode 100644 index 8ac1b15e88a965eb40f3cbfa32926e314053e865..0000000000000000000000000000000000000000 --- a/lib/gitlab/diff/line.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Gitlab - module Diff - class Line - attr_reader :type, :text, :index, :old_pos, :new_pos - - def initialize(text, type, index, old_pos, new_pos) - @text, @type, @index = text, type, index - @old_pos, @new_pos = old_pos, new_pos - end - end - end -end diff --git a/lib/gitlab/diff/line_code.rb b/lib/gitlab/diff/line_code.rb deleted file mode 100644 index f3578ab3d351fca995ff49c4669bd60248aae968..0000000000000000000000000000000000000000 --- a/lib/gitlab/diff/line_code.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Gitlab - module Diff - class LineCode - def self.generate(file_path, new_line_position, old_line_position) - "#{Digest::SHA1.hexdigest(file_path)}_#{old_line_position}_#{new_line_position}" - end - end - end -end diff --git a/lib/gitlab/diff/parser.rb b/lib/gitlab/diff/parser.rb deleted file mode 100644 index c1d9520ddf10deacc2f90daf96af9693618f71c7..0000000000000000000000000000000000000000 --- a/lib/gitlab/diff/parser.rb +++ /dev/null @@ -1,81 +0,0 @@ -module Gitlab - module Diff - class Parser - include Enumerable - - def parse(lines) - @lines = lines - lines_obj = [] - line_obj_index = 0 - line_old = 1 - line_new = 1 - type = nil - - lines_arr = ::Gitlab::InlineDiff.processing lines - - lines_arr.each do |line| - raw_line = line.dup - - next if filename?(line) - - full_line = html_escape(line.gsub(/\n/, '')) - full_line = ::Gitlab::InlineDiff.replace_markers full_line - - if line.match(/^@@ -/) - type = "match" - - line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0 - line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0 - - next if line_old <= 1 && line_new <= 1 #top of file - lines_obj << Gitlab::Diff::Line.new(full_line, type, line_obj_index, line_old, line_new) - line_obj_index += 1 - next - else - type = identification_type(line) - lines_obj << Gitlab::Diff::Line.new(full_line, type, line_obj_index, line_old, line_new) - line_obj_index += 1 - end - - - if line[0] == "+" - line_new += 1 - elsif line[0] == "-" - line_old += 1 - else - line_new += 1 - line_old += 1 - end - end - - lines_obj - end - - def empty? - @lines.empty? - end - - private - - def filename?(line) - line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b', - '--- /tmp/diffy', '+++ /tmp/diffy') - end - - def identification_type(line) - if line[0] == "+" - "new" - elsif line[0] == "-" - "old" - else - nil - end - end - - def html_escape(str) - replacements = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' } - str.gsub(/[&"'><]/, replacements) - end - end - end -end diff --git a/lib/gitlab/force_push_check.rb b/lib/gitlab/force_push_check.rb deleted file mode 100644 index fdb6a35c78d02fef0e24c4dc888a90b304249ff3..0000000000000000000000000000000000000000 --- a/lib/gitlab/force_push_check.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Gitlab - class ForcePushCheck - def self.force_push?(project, oldrev, newrev) - return false if project.empty_repo? - - # Created or deleted branch - if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev) - false - else - missed_refs, _ = Gitlab::Popen.popen(%W(git --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev})) - missed_refs.split("\n").size > 0 - end - end - end -end diff --git a/lib/gitlab/git.rb b/lib/gitlab/git.rb deleted file mode 100644 index 0c350d7c675e1977077944a7c1eff2f5a355c93b..0000000000000000000000000000000000000000 --- a/lib/gitlab/git.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Gitlab - module Git - BLANK_SHA = '0' * 40 - TAG_REF_PREFIX = "refs/tags/" - BRANCH_REF_PREFIX = "refs/heads/" - - class << self - def ref_name(ref) - ref.gsub(/\Arefs\/(tags|heads)\//, '') - end - - def tag_ref?(ref) - ref.start_with?(TAG_REF_PREFIX) - end - - def branch_ref?(ref) - ref.start_with?(BRANCH_REF_PREFIX) - end - - def blank_ref?(ref) - ref == BLANK_SHA - end - end - end -end diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb deleted file mode 100644 index bc72b7528d590839f660af3e978872f941ef3317..0000000000000000000000000000000000000000 --- a/lib/gitlab/git_access.rb +++ /dev/null @@ -1,198 +0,0 @@ -module Gitlab - class GitAccess - DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } - PUSH_COMMANDS = %w{ git-receive-pack } - - attr_reader :actor, :project - - def initialize(actor, project) - @actor = actor - @project = project - end - - def user - return @user if defined?(@user) - - @user = - case actor - when User - actor - when DeployKey - nil - when Key - actor.user - end - end - - def deploy_key - actor if actor.is_a?(DeployKey) - end - - def can_push_to_branch?(ref) - return false unless user - - if project.protected_branch?(ref) && - !(project.developers_can_push_to_protected_branch?(ref) && project.team.developer?(user)) - user.can?(:push_code_to_protected_branches, project) - else - user.can?(:push_code, project) - end - end - - def can_read_project? - if user - user.can?(:read_project, project) - elsif deploy_key - deploy_key.projects.include?(project) - else - false - end - end - - def check(cmd, changes = nil) - case cmd - when *DOWNLOAD_COMMANDS - download_access_check - when *PUSH_COMMANDS - push_access_check(changes) - else - build_status_object(false, "Wrong command") - end - end - - def download_access_check - if user - user_download_access_check - elsif deploy_key - deploy_key_download_access_check - else - raise 'Wrong actor' - end - end - - def push_access_check(changes) - if user - user_push_access_check(changes) - elsif deploy_key - build_status_object(false, "Deploy key not allowed to push") - else - raise 'Wrong actor' - end - end - - def user_download_access_check - if user && user_allowed? && user.can?(:download_code, project) - build_status_object(true) - else - build_status_object(false, "You don't have access") - end - end - - def deploy_key_download_access_check - if can_read_project? - build_status_object(true) - else - build_status_object(false, "Deploy key not allowed to access this project") - end - end - - def user_push_access_check(changes) - unless user && user_allowed? - return build_status_object(false, "You don't have access") - end - - if changes.blank? - return build_status_object(true) - end - - unless project.repository.exists? - return build_status_object(false, "Repository does not exist") - end - - changes = changes.lines if changes.kind_of?(String) - - # Iterate over all changes to find if user allowed all of them to be applied - changes.map(&:strip).reject(&:blank?).each do |change| - status = change_access_check(change) - unless status.allowed? - # If user does not have access to make at least one change - cancel all push - return status - end - end - - build_status_object(true) - end - - def change_access_check(change) - oldrev, newrev, ref = change.split(' ') - - action = - if project.protected_branch?(branch_name(ref)) - protected_branch_action(oldrev, newrev, branch_name(ref)) - elsif protected_tag?(tag_name(ref)) - # Prevent any changes to existing git tag unless user has permissions - :admin_project - else - :push_code - end - - if user.can?(action, project) - build_status_object(true) - else - build_status_object(false, "You don't have permission") - end - end - - def forced_push?(oldrev, newrev) - Gitlab::ForcePushCheck.force_push?(project, oldrev, newrev) - end - - private - - def protected_branch_action(oldrev, newrev, branch_name) - # we dont allow force push to protected branch - if forced_push?(oldrev, newrev) - :force_push_code_to_protected_branches - elsif Gitlab::Git.blank_ref?(newrev) - # and we dont allow remove of protected branch - :remove_protected_branches - elsif project.developers_can_push_to_protected_branch?(branch_name) - :push_code - else - :push_code_to_protected_branches - end - end - - def protected_tag?(tag_name) - project.repository.tag_names.include?(tag_name) - end - - def user_allowed? - Gitlab::UserAccess.allowed?(user) - end - - def branch_name(ref) - ref = ref.to_s - if Gitlab::Git.branch_ref?(ref) - Gitlab::Git.ref_name(ref) - else - nil - end - end - - def tag_name(ref) - ref = ref.to_s - if Gitlab::Git.tag_ref?(ref) - Gitlab::Git.ref_name(ref) - else - nil - end - end - - protected - - def build_status_object(status, message = '') - GitAccessStatus.new(status, message) - end - end -end diff --git a/lib/gitlab/git_access_status.rb b/lib/gitlab/git_access_status.rb deleted file mode 100644 index 5a806ff6e0df59e196f51b4ded5fd41963679168..0000000000000000000000000000000000000000 --- a/lib/gitlab/git_access_status.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Gitlab - class GitAccessStatus - attr_accessor :status, :message - alias_method :allowed?, :status - - def initialize(status, message = '') - @status = status - @message = message - end - - def to_json - { status: @status, message: @message }.to_json - end - end -end diff --git a/lib/gitlab/git_access_wiki.rb b/lib/gitlab/git_access_wiki.rb deleted file mode 100644 index 73d99b96202af29ec1ccd38e35d7a57301c38f27..0000000000000000000000000000000000000000 --- a/lib/gitlab/git_access_wiki.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Gitlab - class GitAccessWiki < GitAccess - def change_access_check(change) - if user.can?(:write_wiki, project) - build_status_object(true) - else - build_status_object(false, "You don't have access") - end - end - end -end diff --git a/lib/gitlab/git_logger.rb b/lib/gitlab/git_logger.rb deleted file mode 100644 index 9e02ccc0f44e2552c4e4df50520da18ec9521782..0000000000000000000000000000000000000000 --- a/lib/gitlab/git_logger.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Gitlab - class GitLogger < Gitlab::Logger - def self.file_name_noext - 'githost' - end - - def format_message(severity, timestamp, progname, msg) - "#{timestamp.to_s(:long)} -> #{severity} -> #{msg}\n" - end - end -end diff --git a/lib/gitlab/git_ref_validator.rb b/lib/gitlab/git_ref_validator.rb deleted file mode 100644 index 39d17def93073286b1f37b899dd7c9bba0e4d76e..0000000000000000000000000000000000000000 --- a/lib/gitlab/git_ref_validator.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Gitlab - module GitRefValidator - extend self - # Validates a given name against the git reference specification - # - # Returns true for a valid reference name, false otherwise - def validate(ref_name) - Gitlab::Utils.system_silent( - %W(git check-ref-format refs/#{ref_name})) - end - end -end diff --git a/lib/gitlab/github_import/client.rb b/lib/gitlab/github_import/client.rb deleted file mode 100644 index 270cbcd9ccd92b9ec35da9d90ec688b81f05b983..0000000000000000000000000000000000000000 --- a/lib/gitlab/github_import/client.rb +++ /dev/null @@ -1,53 +0,0 @@ -module Gitlab - module GithubImport - class Client - attr_reader :client, :api - - def initialize(access_token) - @client = ::OAuth2::Client.new( - config.app_id, - config.app_secret, - github_options - ) - - if access_token - ::Octokit.auto_paginate = true - @api = ::Octokit::Client.new(access_token: access_token) - end - end - - def authorize_url(redirect_uri) - client.auth_code.authorize_url({ - redirect_uri: redirect_uri, - scope: "repo, user, user:email" - }) - end - - def get_token(code) - client.auth_code.get_token(code).token - end - - def method_missing(method, *args, &block) - if api.respond_to?(method) - api.send(method, *args, &block) - else - super(method, *args, &block) - end - end - - def respond_to?(method) - api.respond_to?(method) || super - end - - private - - def config - Gitlab.config.omniauth.providers.find{|provider| provider.name == "github"} - end - - def github_options - OmniAuth::Strategies::GitHub.default_options[:client_options].symbolize_keys - end - end - end -end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb deleted file mode 100644 index 23832b3233ce048bb9b7cc01836bba1421cc9c31..0000000000000000000000000000000000000000 --- a/lib/gitlab/github_import/importer.rb +++ /dev/null @@ -1,46 +0,0 @@ -module Gitlab - module GithubImport - class Importer - attr_reader :project, :client - - def initialize(project) - @project = project - @client = Client.new(project.creator.github_access_token) - @formatter = Gitlab::ImportFormatter.new - end - - def execute - #Issues && Comments - client.list_issues(project.import_source, state: :all).each do |issue| - if issue.pull_request.nil? - - body = @formatter.author_line(issue.user.login, issue.body) - - if issue.comments > 0 - body += @formatter.comments_header - - client.issue_comments(project.import_source, issue.number).each do |c| - body += @formatter.comment(c.user.login, c.created_at, c.body) - end - end - - project.issues.create!( - description: body, - title: issue.title, - state: issue.state == 'closed' ? 'closed' : 'opened', - author_id: gl_user_id(project, issue.user.id) - ) - end - end - end - - private - - def gl_user_id(project, github_id) - user = User.joins(:identities). - find_by("identities.extern_uid = ? AND identities.provider = 'github'", github_id.to_s) - (user && user.id) || project.creator_id - end - end - end -end diff --git a/lib/gitlab/github_import/project_creator.rb b/lib/gitlab/github_import/project_creator.rb deleted file mode 100644 index 2723eec933eaea9a28b1b4afe2b277188d3f4452..0000000000000000000000000000000000000000 --- a/lib/gitlab/github_import/project_creator.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Gitlab - module GithubImport - class ProjectCreator - attr_reader :repo, :namespace, :current_user - - def initialize(repo, namespace, current_user) - @repo = repo - @namespace = namespace - @current_user = current_user - end - - def execute - ::Projects::CreateService.new(current_user, - name: repo.name, - path: repo.name, - description: repo.description, - namespace_id: namespace.id, - visibility_level: repo.private ? Gitlab::VisibilityLevel::PRIVATE : Gitlab::VisibilityLevel::PUBLIC, - import_type: "github", - import_source: repo.full_name, - import_url: repo.clone_url.sub("https://", "https://#{current_user.github_access_token}@") - ).execute - end - end - end -end diff --git a/lib/gitlab/gitlab_import/client.rb b/lib/gitlab/gitlab_import/client.rb deleted file mode 100644 index 9c00896c913bf080e0aee65bb8d581d2e315b45b..0000000000000000000000000000000000000000 --- a/lib/gitlab/gitlab_import/client.rb +++ /dev/null @@ -1,82 +0,0 @@ -module Gitlab - module GitlabImport - class Client - attr_reader :client, :api - - PER_PAGE = 100 - - def initialize(access_token) - @client = ::OAuth2::Client.new( - config.app_id, - config.app_secret, - gitlab_options - ) - - if access_token - @api = OAuth2::AccessToken.from_hash(@client, access_token: access_token) - end - end - - def authorize_url(redirect_uri) - client.auth_code.authorize_url({ - redirect_uri: redirect_uri, - scope: "api" - }) - end - - def get_token(code, redirect_uri) - client.auth_code.get_token(code, redirect_uri: redirect_uri).token - end - - def user - api.get("/api/v3/user").parsed - end - - def issues(project_identifier) - lazy_page_iterator(PER_PAGE) do |page| - api.get("/api/v3/projects/#{project_identifier}/issues?per_page=#{PER_PAGE}&page=#{page}").parsed - end - end - - def issue_comments(project_identifier, issue_id) - lazy_page_iterator(PER_PAGE) do |page| - api.get("/api/v3/projects/#{project_identifier}/issues/#{issue_id}/notes?per_page=#{PER_PAGE}&page=#{page}").parsed - end - end - - def project(id) - api.get("/api/v3/projects/#{id}").parsed - end - - def projects - lazy_page_iterator(PER_PAGE) do |page| - api.get("/api/v3/projects?per_page=#{PER_PAGE}&page=#{page}").parsed - end - end - - private - - def lazy_page_iterator(per_page) - Enumerator.new do |y| - page = 1 - loop do - items = yield(page) - items.each do |item| - y << item - end - break if items.empty? || items.size < per_page - page += 1 - end - end - end - - def config - Gitlab.config.omniauth.providers.find{|provider| provider.name == "gitlab"} - end - - def gitlab_options - OmniAuth::Strategies::GitLab.default_options[:client_options].symbolize_keys - end - end - end -end diff --git a/lib/gitlab/gitlab_import/importer.rb b/lib/gitlab/gitlab_import/importer.rb deleted file mode 100644 index c5304a0699b9e1c424040e1a36b75fee3165507f..0000000000000000000000000000000000000000 --- a/lib/gitlab/gitlab_import/importer.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Gitlab - module GitlabImport - class Importer - attr_reader :project, :client - - def initialize(project) - @project = project - @client = Client.new(project.creator.gitlab_access_token) - @formatter = Gitlab::ImportFormatter.new - end - - def execute - project_identifier = URI.encode(project.import_source, '/') - - #Issues && Comments - issues = client.issues(project_identifier) - - issues.each do |issue| - body = @formatter.author_line(issue["author"]["name"], issue["description"]) - - comments = client.issue_comments(project_identifier, issue["id"]) - - if comments.any? - body += @formatter.comments_header - end - - comments.each do |comment| - body += @formatter.comment(comment["author"]["name"], comment["created_at"], comment["body"]) - end - - project.issues.create!( - description: body, - title: issue["title"], - state: issue["state"], - author_id: gl_user_id(project, issue["author"]["id"]) - ) - end - - true - end - - private - - def gl_user_id(project, gitlab_id) - user = User.joins(:identities).find_by("identities.extern_uid = ? AND identities.provider = 'gitlab'", gitlab_id.to_s) - (user && user.id) || project.creator_id - end - end - end -end diff --git a/lib/gitlab/gitlab_import/project_creator.rb b/lib/gitlab/gitlab_import/project_creator.rb deleted file mode 100644 index f0d7141bf566ff163fcd243dd523590e98e38fbf..0000000000000000000000000000000000000000 --- a/lib/gitlab/gitlab_import/project_creator.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Gitlab - module GitlabImport - class ProjectCreator - attr_reader :repo, :namespace, :current_user - - def initialize(repo, namespace, current_user) - @repo = repo - @namespace = namespace - @current_user = current_user - end - - def execute - ::Projects::CreateService.new(current_user, - name: repo["name"], - path: repo["path"], - description: repo["description"], - namespace_id: namespace.id, - visibility_level: repo["visibility_level"], - import_type: "gitlab", - import_source: repo["path_with_namespace"], - import_url: repo["http_url_to_repo"].sub("://", "://oauth2:#{current_user.gitlab_access_token}@") - ).execute - end - end - end -end diff --git a/lib/gitlab/gitorious_import/client.rb b/lib/gitlab/gitorious_import/client.rb deleted file mode 100644 index 8cdc3d4afae73a9434b72b3547393eb35de255a0..0000000000000000000000000000000000000000 --- a/lib/gitlab/gitorious_import/client.rb +++ /dev/null @@ -1,31 +0,0 @@ -module Gitlab - module GitoriousImport - GITORIOUS_HOST = "https://gitorious.org" - - class Client - attr_reader :repo_list - - def initialize(repo_list) - @repo_list = repo_list - end - - def authorize_url(redirect_uri) - "#{GITORIOUS_HOST}/gitlab-import?callback_url=#{redirect_uri}" - end - - def repos - @repos ||= repo_names.map { |full_name| Repository.new(full_name) } - end - - def repo(id) - repos.find { |repo| repo.id == id } - end - - private - - def repo_names - repo_list.to_s.split(',').map(&:strip).reject(&:blank?) - end - end - end -end diff --git a/lib/gitlab/gitorious_import/project_creator.rb b/lib/gitlab/gitorious_import/project_creator.rb deleted file mode 100644 index cc9a91c91f4538faa2158d8b11234874863b128e..0000000000000000000000000000000000000000 --- a/lib/gitlab/gitorious_import/project_creator.rb +++ /dev/null @@ -1,26 +0,0 @@ -module Gitlab - module GitoriousImport - class ProjectCreator - attr_reader :repo, :namespace, :current_user - - def initialize(repo, namespace, current_user) - @repo = repo - @namespace = namespace - @current_user = current_user - end - - def execute - ::Projects::CreateService.new(current_user, - name: repo.name, - path: repo.path, - description: repo.description, - namespace_id: namespace.id, - visibility_level: Gitlab::VisibilityLevel::PUBLIC, - import_type: "gitorious", - import_source: repo.full_name, - import_url: repo.import_url - ).execute - end - end - end -end diff --git a/lib/gitlab/gitorious_import/repository.rb b/lib/gitlab/gitorious_import/repository.rb deleted file mode 100644 index f702797dc6e06adff2a8b92522119aa4325e48f9..0000000000000000000000000000000000000000 --- a/lib/gitlab/gitorious_import/repository.rb +++ /dev/null @@ -1,37 +0,0 @@ -module Gitlab - module GitoriousImport - GITORIOUS_HOST = "https://gitorious.org" - - Repository = Struct.new(:full_name) do - def id - Digest::SHA1.hexdigest(full_name) - end - - def namespace - segments.first - end - - def path - segments.last - end - - def name - path.titleize - end - - def description - "" - end - - def import_url - "#{GITORIOUS_HOST}/#{full_name}.git" - end - - private - - def segments - full_name.split('/') - end - end - end -end diff --git a/lib/gitlab/google_code_import/client.rb b/lib/gitlab/google_code_import/client.rb deleted file mode 100644 index 02f31e45f885f8b753610eac2bec2e786286c227..0000000000000000000000000000000000000000 --- a/lib/gitlab/google_code_import/client.rb +++ /dev/null @@ -1,48 +0,0 @@ -module Gitlab - module GoogleCodeImport - class Client - attr_reader :raw_data - - def self.mask_email(author) - parts = author.split("@", 2) - parts[0] = "#{parts[0][0...-3]}..." - parts.join("@") - end - - def initialize(raw_data) - @raw_data = raw_data - end - - def valid? - raw_data.is_a?(Hash) && raw_data["kind"] == "projecthosting#user" && raw_data.has_key?("projects") - end - - def repos - @repos ||= raw_data["projects"].map { |raw_repo| GoogleCodeImport::Repository.new(raw_repo) }.select(&:git?) - end - - def repo(id) - repos.find { |repo| repo.id == id } - end - - def user_map - user_map = Hash.new { |hash, user| hash[user] = self.class.mask_email(user) } - - repos.each do |repo| - next unless repo.valid? && repo.issues - - repo.issues.each do |raw_issue| - # Touching is enough to add the entry and masked email. - user_map[raw_issue["author"]["name"]] - - raw_issue["comments"]["items"].each do |raw_comment| - user_map[raw_comment["author"]["name"]] - end - end - end - - Hash[user_map.sort] - end - end - end -end diff --git a/lib/gitlab/google_code_import/repository.rb b/lib/gitlab/google_code_import/repository.rb deleted file mode 100644 index ad33fc2cad225e288abfc280f0ed06067eb6e742..0000000000000000000000000000000000000000 --- a/lib/gitlab/google_code_import/repository.rb +++ /dev/null @@ -1,43 +0,0 @@ -module Gitlab - module GoogleCodeImport - class Repository - attr_accessor :raw_data - - def initialize(raw_data) - @raw_data = raw_data - end - - def valid? - raw_data.is_a?(Hash) && raw_data["kind"] == "projecthosting#project" - end - - def id - raw_data["externalId"] - end - - def name - raw_data["name"] - end - - def summary - raw_data["summary"] - end - - def description - raw_data["description"] - end - - def git? - raw_data["versionControlSystem"] == "git" - end - - def import_url - raw_data["repositoryUrls"].first - end - - def issues - raw_data["issues"] && raw_data["issues"]["items"] - end - end - end -end diff --git a/lib/gitlab/graphs/commits.rb b/lib/gitlab/graphs/commits.rb deleted file mode 100644 index 2122339d2db89cbe72393837b713e274626d2dff..0000000000000000000000000000000000000000 --- a/lib/gitlab/graphs/commits.rb +++ /dev/null @@ -1,49 +0,0 @@ -module Gitlab - module Graphs - class Commits - attr_reader :commits, :start_date, :end_date, :duration, - :commits_per_week_days, :commits_per_time, :commits_per_month - - def initialize(commits) - @commits = commits - @start_date = commits.last.committed_date.to_date - @end_date = commits.first.committed_date.to_date - @duration = (@end_date - @start_date).to_i - - collect_data - end - - def authors - @authors ||= @commits.map(&:author_email).uniq.size - end - - def commit_per_day - @commit_per_day ||= (@commits.size.to_f / @duration).round(1) - end - - def collect_data - @commits_per_week_days = {} - Date::DAYNAMES.each { |day| @commits_per_week_days[day] = 0 } - - @commits_per_time = {} - (0..23).to_a.each { |hour| @commits_per_time[hour] = 0 } - - @commits_per_month = {} - (1..31).to_a.each { |day| @commits_per_month[day] = 0 } - - @commits.each do |commit| - hour = commit.committed_date.strftime('%k').to_i - day_of_month = commit.committed_date.strftime('%e').to_i - weekday = commit.committed_date.strftime('%A') - - @commits_per_week_days[weekday] ||= 0 - @commits_per_week_days[weekday] += 1 - @commits_per_time[hour] ||= 0 - @commits_per_time[hour] += 1 - @commits_per_month[day_of_month] ||= 0 - @commits_per_month[day_of_month] += 1 - end - end - end - end -end diff --git a/lib/gitlab/identifier.rb b/lib/gitlab/identifier.rb deleted file mode 100644 index 6e4de197eeb3b31bbe6ba44c143decea3b811eaf..0000000000000000000000000000000000000000 --- a/lib/gitlab/identifier.rb +++ /dev/null @@ -1,23 +0,0 @@ -# Detect user based on identifier like -# key-13 or user-36 or last commit -module Gitlab - module Identifier - def identify(identifier, project, newrev) - if identifier.blank? - # Local push from gitlab - email = project.repository.commit(newrev).author_email rescue nil - User.find_by(email: email) if email - - elsif identifier =~ /\Auser-\d+\Z/ - # git push over http - user_id = identifier.gsub("user-", "") - User.find_by(id: user_id) - - elsif identifier =~ /\Akey-\d+\Z/ - # git push over ssh - key_id = identifier.gsub("key-", "") - Key.find_by(id: key_id).try(:user) - end - end - end -end diff --git a/lib/gitlab/import_formatter.rb b/lib/gitlab/import_formatter.rb deleted file mode 100644 index 72e041a90b1d59824ef958a56b11ea3bf3affd67..0000000000000000000000000000000000000000 --- a/lib/gitlab/import_formatter.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Gitlab - class ImportFormatter - def comment(author, date, body) - "\n\n*By #{author} on #{date}*\n\n#{body}" - end - - def comments_header - "\n\n\n**Imported comments:**\n" - end - - def author_line(author, body) - "*Created by: #{author}*\n\n#{body}" - end - end -end diff --git a/lib/gitlab/inline_diff.rb b/lib/gitlab/inline_diff.rb deleted file mode 100644 index 3517ecdf5cf003a710a160d42e82eba90eeb15f7..0000000000000000000000000000000000000000 --- a/lib/gitlab/inline_diff.rb +++ /dev/null @@ -1,78 +0,0 @@ -module Gitlab - class InlineDiff - class << self - - START = "#!idiff-start!#" - FINISH = "#!idiff-finish!#" - - def processing(diff_arr) - indexes = _indexes_of_changed_lines diff_arr - - indexes.each do |index| - first_line = diff_arr[index+1] - second_line = diff_arr[index+2] - max_length = [first_line.size, second_line.size].max - - # Skip inline diff if empty line was replaced with content - next if first_line == "-\n" - - first_the_same_symbols = 0 - (0..max_length + 1).each do |i| - first_the_same_symbols = i - 1 - if first_line[i] != second_line[i] && i > 0 - break - end - end - - first_token = first_line[0..first_the_same_symbols][1..-1] - start = first_token + START - - if first_token.empty? - # In case if we remove string of spaces in commit - diff_arr[index+1].sub!("-", "-" => "-#{START}") - diff_arr[index+2].sub!("+", "+" => "+#{START}") - else - diff_arr[index+1].sub!(first_token, first_token => start) - diff_arr[index+2].sub!(first_token, first_token => start) - end - - last_the_same_symbols = 0 - (1..max_length + 1).each do |i| - last_the_same_symbols = -i - shortest_line = second_line.size > first_line.size ? first_line : second_line - if ( first_line[-i] != second_line[-i] ) || "#{first_token}#{START}".size == shortest_line[1..-i].size - break - end - end - last_the_same_symbols += 1 - last_token = first_line[last_the_same_symbols..-1] - diff_arr[index+1].sub!(/#{Regexp.escape(last_token)}$/, FINISH + last_token) - diff_arr[index+2].sub!(/#{Regexp.escape(last_token)}$/, FINISH + last_token) - end - diff_arr - end - - def _indexes_of_changed_lines(diff_arr) - chain_of_first_symbols = "" - diff_arr.each_with_index do |line, i| - chain_of_first_symbols += line[0] - end - chain_of_first_symbols.gsub!(/[^\-\+]/, "#") - - offset = 0 - indexes = [] - while index = chain_of_first_symbols.index("#-+#", offset) - indexes << index - offset = index + 1 - end - indexes - end - - def replace_markers(line) - line.gsub!(START, "") - line.gsub!(FINISH, "") - line - end - end - end -end diff --git a/lib/gitlab/issues_labels.rb b/lib/gitlab/issues_labels.rb deleted file mode 100644 index 1bec60882925b8d3a129df8676a2b0389ac08ef3..0000000000000000000000000000000000000000 --- a/lib/gitlab/issues_labels.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Gitlab - class IssuesLabels - class << self - def generate(project) - red = '#d9534f' - yellow = '#f0ad4e' - blue = '#428bca' - green = '#5cb85c' - - labels = [ - { title: "bug", color: red }, - { title: "critical", color: red }, - { title: "confirmed", color: red }, - { title: "documentation", color: yellow }, - { title: "support", color: yellow }, - { title: "discussion", color: blue }, - { title: "suggestion", color: blue }, - { title: "enhancement", color: green } - ] - - labels.each do |label| - project.labels.create(label) - end - end - end - end -end diff --git a/lib/gitlab/key_fingerprint.rb b/lib/gitlab/key_fingerprint.rb deleted file mode 100644 index baf52ff750de330c914679befd54b4ef9e436563..0000000000000000000000000000000000000000 --- a/lib/gitlab/key_fingerprint.rb +++ /dev/null @@ -1,55 +0,0 @@ -module Gitlab - class KeyFingerprint - include Gitlab::Popen - - attr_accessor :key - - def initialize(key) - @key = key - end - - def fingerprint - cmd_status = 0 - cmd_output = '' - - Tempfile.open('gitlab_key_file') do |file| - file.puts key - file.rewind - - cmd = [] - cmd.push *%W(ssh-keygen) - cmd.push *%W(-E md5) if explicit_fingerprint_algorithm? - cmd.push *%W(-lf #{file.path}) - - cmd_output, cmd_status = popen(cmd, '/tmp') - end - - return nil unless cmd_status.zero? - - # 16 hex bytes separated by ':', optionally starting with "MD5:" - fingerprint_matches = cmd_output.match(/(MD5:)?(?(\h{2}:){15}\h{2})/) - return nil unless fingerprint_matches - - fingerprint_matches[:fingerprint] - end - - private - - def explicit_fingerprint_algorithm? - # OpenSSH 6.8 introduces a new default output format for fingerprints. - # Check the version and decide which command to use. - - version_output, version_status = popen(%W(ssh -V)) - return false unless version_status.zero? - - version_matches = version_output.match(/OpenSSH_(?\d+)\.(?\d+)/) - return false unless version_matches - - version_info = Gitlab::VersionInfo.new(version_matches[:major].to_i, version_matches[:minor].to_i) - - required_version_info = Gitlab::VersionInfo.new(6, 8) - - version_info >= required_version_info - end - end -end diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb deleted file mode 100644 index 960fb3849b47fa2547232ef8d4f720e8a235fdce..0000000000000000000000000000000000000000 --- a/lib/gitlab/ldap/access.rb +++ /dev/null @@ -1,62 +0,0 @@ -# LDAP authorization model -# -# * Check if we are allowed access (not blocked) -# -module Gitlab - module LDAP - class Access - attr_reader :adapter, :provider, :user - - def self.open(user, &block) - Gitlab::LDAP::Adapter.open(user.ldap_identity.provider) do |adapter| - block.call(self.new(user, adapter)) - end - end - - def self.allowed?(user) - self.open(user) do |access| - if access.allowed? - user.last_credential_check_at = Time.now - user.save - true - else - false - end - end - end - - def initialize(user, adapter=nil) - @adapter = adapter - @user = user - @provider = user.ldap_identity.provider - end - - def allowed? - if Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter) - return true unless ldap_config.active_directory - - # Block user in GitLab if he/she was blocked in AD - if Gitlab::LDAP::Person.disabled_via_active_directory?(user.ldap_identity.extern_uid, adapter) - user.block unless user.blocked? - false - else - user.activate if user.blocked? - true - end - else - false - end - rescue - false - end - - def adapter - @adapter ||= Gitlab::LDAP::Adapter.new(provider) - end - - def ldap_config - Gitlab::LDAP::Config.new(provider) - end - end - end -end diff --git a/lib/gitlab/ldap/adapter.rb b/lib/gitlab/ldap/adapter.rb deleted file mode 100644 index 577a890a7d9879f8cc9f51a454644757c1dd6ff6..0000000000000000000000000000000000000000 --- a/lib/gitlab/ldap/adapter.rb +++ /dev/null @@ -1,89 +0,0 @@ -module Gitlab - module LDAP - class Adapter - attr_reader :provider, :ldap - - def self.open(provider, &block) - Net::LDAP.open(config(provider).adapter_options) do |ldap| - block.call(self.new(provider, ldap)) - end - end - - def self.config(provider) - Gitlab::LDAP::Config.new(provider) - end - - def initialize(provider, ldap=nil) - @provider = provider - @ldap = ldap || Net::LDAP.new(config.adapter_options) - end - - def config - Gitlab::LDAP::Config.new(provider) - end - - def users(field, value, limit = nil) - if field.to_sym == :dn - options = { - base: value, - scope: Net::LDAP::SearchScope_BaseObject - } - else - options = { - base: config.base, - filter: Net::LDAP::Filter.eq(field, value) - } - end - - if config.user_filter.present? - user_filter = Net::LDAP::Filter.construct(config.user_filter) - - options[:filter] = if options[:filter] - Net::LDAP::Filter.join(options[:filter], user_filter) - else - user_filter - end - end - - if limit.present? - options.merge!(size: limit) - end - - entries = ldap_search(options).select do |entry| - entry.respond_to? config.uid - end - - entries.map do |entry| - Gitlab::LDAP::Person.new(entry, provider) - end - end - - def user(*args) - users(*args).first - end - - def dn_matches_filter?(dn, filter) - ldap_search(base: dn, - filter: filter, - scope: Net::LDAP::SearchScope_BaseObject, - attributes: %w{dn}).any? - end - - def ldap_search(*args) - results = ldap.search(*args) - - if results.nil? - response = ldap.get_operation_result - - unless response.code.zero? - Rails.logger.warn("LDAP search error: #{response.message}") - end - - [] - else - results - end - end - end - end -end diff --git a/lib/gitlab/ldap/authentication.rb b/lib/gitlab/ldap/authentication.rb deleted file mode 100644 index 649cf3194b8a895b0a494740a73284c54602fe4b..0000000000000000000000000000000000000000 --- a/lib/gitlab/ldap/authentication.rb +++ /dev/null @@ -1,71 +0,0 @@ -# This calls helps to authenticate to LDAP by providing username and password -# -# Since multiple LDAP servers are supported, it will loop through all of them -# until a valid bind is found -# - -module Gitlab - module LDAP - class Authentication - def self.login(login, password) - return unless Gitlab::LDAP::Config.enabled? - return unless login.present? && password.present? - - auth = nil - # loop through providers until valid bind - providers.find do |provider| - auth = new(provider) - auth.login(login, password) # true will exit the loop - end - - # If (login, password) was invalid for all providers, the value of auth is now the last - # Gitlab::LDAP::Authentication instance we tried. - auth.user - end - - def self.providers - Gitlab::LDAP::Config.providers - end - - attr_accessor :provider, :ldap_user - - def initialize(provider) - @provider = provider - end - - def login(login, password) - @ldap_user = adapter.bind_as( - filter: user_filter(login), - size: 1, - password: password - ) - end - - def adapter - OmniAuth::LDAP::Adaptor.new(config.options.symbolize_keys) - end - - def config - Gitlab::LDAP::Config.new(provider) - end - - def user_filter(login) - filter = Net::LDAP::Filter.equals(config.uid, login) - - # Apply LDAP user filter if present - if config.user_filter.present? - filter = Net::LDAP::Filter.join( - filter, - Net::LDAP::Filter.construct(config.user_filter) - ) - end - filter - end - - def user - return nil unless ldap_user - Gitlab::LDAP::User.find_by_uid_and_provider(ldap_user.dn, provider) - end - end - end -end diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb deleted file mode 100644 index d2ffa2e1fe8d09df464705b1fc5f250014b5c648..0000000000000000000000000000000000000000 --- a/lib/gitlab/ldap/config.rb +++ /dev/null @@ -1,122 +0,0 @@ -# Load a specific server configuration -module Gitlab - module LDAP - class Config - attr_accessor :provider, :options - - def self.enabled? - Gitlab.config.ldap.enabled - end - - def self.servers - Gitlab.config.ldap.servers.values - end - - def self.providers - servers.map {|server| server['provider_name'] } - end - - def self.valid_provider?(provider) - providers.include?(provider) - end - - def self.invalid_provider(provider) - raise "Unknown provider (#{provider}). Available providers: #{providers}" - end - - def initialize(provider) - if self.class.valid_provider?(provider) - @provider = provider - else - self.class.invalid_provider(provider) - end - @options = config_for(@provider) # Use @provider, not provider - end - - def enabled? - base_config.enabled - end - - def adapter_options - { - host: options['host'], - port: options['port'], - encryption: encryption - }.tap do |options| - options.merge!(auth_options) if has_auth? - end - end - - def base - options['base'] - end - - def uid - options['uid'] - end - - def sync_ssh_keys? - sync_ssh_keys.present? - end - - # The LDAP attribute in which the ssh keys are stored - def sync_ssh_keys - options['sync_ssh_keys'] - end - - def user_filter - options['user_filter'] - end - - def group_base - options['group_base'] - end - - def admin_group - options['admin_group'] - end - - def active_directory - options['active_directory'] - end - - def block_auto_created_users - options['block_auto_created_users'] - end - - protected - def base_config - Gitlab.config.ldap - end - - def config_for(provider) - base_config.servers.values.find { |server| server['provider_name'] == provider } - end - - def encryption - case options['method'].to_s - when 'ssl' - :simple_tls - when 'tls' - :start_tls - else - nil - end - end - - def auth_options - { - auth: { - method: :simple, - username: options['bind_dn'], - password: options['password'] - } - } - end - - def has_auth? - options['password'] || options['bind_dn'] - end - end - end -end diff --git a/lib/gitlab/ldap/person.rb b/lib/gitlab/ldap/person.rb deleted file mode 100644 index b81f3e8e8f5b8d18312cc583b5239de090663853..0000000000000000000000000000000000000000 --- a/lib/gitlab/ldap/person.rb +++ /dev/null @@ -1,61 +0,0 @@ -module Gitlab - module LDAP - class Person - # Active Directory-specific LDAP filter that checks if bit 2 of the - # userAccountControl attribute is set. - # Source: http://ctogonewild.com/2009/09/03/bitmask-searches-in-ldap/ - AD_USER_DISABLED = Net::LDAP::Filter.ex("userAccountControl:1.2.840.113556.1.4.803", "2") - - attr_accessor :entry, :provider - - def self.find_by_uid(uid, adapter) - uid = Net::LDAP::Filter.escape(uid) - adapter.user(adapter.config.uid, uid) - end - - def self.find_by_dn(dn, adapter) - adapter.user('dn', dn) - end - - def self.disabled_via_active_directory?(dn, adapter) - adapter.dn_matches_filter?(dn, AD_USER_DISABLED) - end - - def initialize(entry, provider) - Rails.logger.debug { "Instantiating #{self.class.name} with LDIF:\n#{entry.to_ldif}" } - @entry = entry - @provider = provider - end - - def name - entry.cn.first - end - - def uid - entry.send(config.uid).first - end - - def username - uid - end - - def email - entry.try(:mail) - end - - def dn - entry.dn - end - - private - - def entry - @entry - end - - def config - @config ||= Gitlab::LDAP::Config.new(provider) - end - end - end -end diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb deleted file mode 100644 index f7f3ba9ad7d3322b4afb50215224de2bdb27c928..0000000000000000000000000000000000000000 --- a/lib/gitlab/ldap/user.rb +++ /dev/null @@ -1,71 +0,0 @@ -require 'gitlab/o_auth/user' - -# LDAP extension for User model -# -# * Find or create user from omniauth.auth data -# * Links LDAP account with existing user -# * Auth LDAP user with login and password -# -module Gitlab - module LDAP - class User < Gitlab::OAuth::User - class << self - def find_by_uid_and_provider(uid, provider) - # LDAP distinguished name is case-insensitive - identity = ::Identity. - where(provider: provider). - where('lower(extern_uid) = ?', uid.downcase).last - identity && identity.user - end - end - - def initialize(auth_hash) - super - update_user_attributes - end - - # instance methods - def gl_user - @gl_user ||= find_by_uid_and_provider || find_by_email || build_new_user - end - - def find_by_uid_and_provider - self.class.find_by_uid_and_provider( - auth_hash.uid.downcase, auth_hash.provider) - end - - def find_by_email - ::User.find_by(email: auth_hash.email) - end - - def update_user_attributes - return unless persisted? - - gl_user.skip_reconfirmation! - gl_user.email = auth_hash.email - - # Build new identity only if we dont have have same one - gl_user.identities.find_or_initialize_by(provider: auth_hash.provider, - extern_uid: auth_hash.uid) - - gl_user - end - - def changed? - gl_user.changed? || gl_user.identities.any?(&:changed?) - end - - def block_after_signup? - ldap_config.block_auto_created_users - end - - def allowed? - Gitlab::LDAP::Access.allowed?(gl_user) - end - - def ldap_config - Gitlab::LDAP::Config.new(auth_hash.provider) - end - end - end -end diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb deleted file mode 100644 index 59b21149a9a209976e2b5e6394899442a5906291..0000000000000000000000000000000000000000 --- a/lib/gitlab/logger.rb +++ /dev/null @@ -1,32 +0,0 @@ -module Gitlab - class Logger < ::Logger - def self.file_name - file_name_noext + '.log' - end - - def self.error(message) - build.error(message) - end - - def self.info(message) - build.info(message) - end - - def self.read_latest - path = Rails.root.join("log", file_name) - self.build unless File.exist?(path) - tail_output, _ = Gitlab::Popen.popen(%W(tail -n 2000 #{path})) - tail_output.split("\n") - end - - def self.read_latest_for(filename) - path = Rails.root.join("log", filename) - tail_output, _ = Gitlab::Popen.popen(%W(tail -n 2000 #{path})) - tail_output.split("\n") - end - - def self.build - new(Rails.root.join("log", file_name)) - end - end -end diff --git a/lib/gitlab/markdown_helper.rb b/lib/gitlab/markdown_helper.rb deleted file mode 100644 index 5e3cfc0585b32470139ea8666be689ad17ab25ae..0000000000000000000000000000000000000000 --- a/lib/gitlab/markdown_helper.rb +++ /dev/null @@ -1,29 +0,0 @@ -module Gitlab - module MarkdownHelper - module_function - - # Public: Determines if a given filename is compatible with GitHub::Markup. - # - # filename - Filename string to check - # - # Returns boolean - def markup?(filename) - filename.downcase.end_with?(*%w(.textile .rdoc .org .creole .wiki - .mediawiki .rst .adoc .asciidoc .asc)) - end - - # Public: Determines if a given filename is compatible with - # GitLab-flavored Markdown. - # - # filename - Filename string to check - # - # Returns boolean - def gitlab_markdown?(filename) - filename.downcase.end_with?(*%w(.mdown .md .markdown)) - end - - def previewable?(filename) - gitlab_markdown?(filename) || markup?(filename) - end - end -end diff --git a/lib/gitlab/middleware/static.rb b/lib/gitlab/middleware/static.rb deleted file mode 100644 index 85ffa8aca68ccaae90c7bcf3159b2d33d734a887..0000000000000000000000000000000000000000 --- a/lib/gitlab/middleware/static.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Gitlab - module Middleware - class Static < ActionDispatch::Static - UPLOADS_REGEX = /\A\/uploads(\/|\z)/.freeze - - def call(env) - return @app.call(env) if env['PATH_INFO'] =~ UPLOADS_REGEX - - super - end - end - end -end diff --git a/lib/gitlab/note_data_builder.rb b/lib/gitlab/note_data_builder.rb deleted file mode 100644 index 644dec45dca6db0eec39da424f2d443c2a2abc27..0000000000000000000000000000000000000000 --- a/lib/gitlab/note_data_builder.rb +++ /dev/null @@ -1,77 +0,0 @@ -module Gitlab - class NoteDataBuilder - class << self - # Produce a hash of post-receive data - # - # For all notes: - # - # data = { - # object_kind: "note", - # user: { - # name: String, - # username: String, - # avatar_url: String - # } - # project_id: Integer, - # repository: { - # name: String, - # url: String, - # description: String, - # homepage: String, - # } - # object_attributes: { - # - # } - # : { - # } - # note-specific data is a hash with one of the following keys and contains - # the hook data for that type. - # - commit - # - issue - # - merge_request - # - snippet - # - def build(note, user) - project = note.project - data = build_base_data(project, user, note) - - if note.for_commit? - data[:commit] = build_data_for_commit(project, user, note) - elsif note.for_issue? - data[:issue] = note.noteable.hook_attrs - elsif note.for_merge_request? - data[:merge_request] = note.noteable.hook_attrs - elsif note.for_project_snippet? - data[:snippet] = note.noteable.hook_attrs - end - - data - end - - def build_base_data(project, user, note) - base_data = { - object_kind: "note", - user: user.hook_attrs, - project_id: project.id, - repository: { - name: project.name, - url: project.url_to_repo, - description: project.description, - homepage: project.web_url, - }, - object_attributes: note.hook_attrs - } - - base_data[:object_attributes][:url] = - Gitlab::UrlBuilder.new(:note).build(note.id) - base_data - end - - def build_data_for_commit(project, user, note) - # commit_id is the SHA hash - commit = project.repository.commit(note.commit_id) - commit.hook_attrs(project) - end - end - end -end diff --git a/lib/gitlab/o_auth/auth_hash.rb b/lib/gitlab/o_auth/auth_hash.rb deleted file mode 100644 index ce52beec78e64a5c4206cb57726f5b8659fcc6b2..0000000000000000000000000000000000000000 --- a/lib/gitlab/o_auth/auth_hash.rb +++ /dev/null @@ -1,54 +0,0 @@ -# Class to parse and transform the info provided by omniauth -# -module Gitlab - module OAuth - class AuthHash - attr_reader :auth_hash - def initialize(auth_hash) - @auth_hash = auth_hash - end - - def uid - auth_hash.uid.to_s - end - - def provider - auth_hash.provider - end - - def info - auth_hash.info - end - - def name - (info.try(:name) || full_name).to_s.force_encoding('utf-8') - end - - def full_name - "#{info.first_name} #{info.last_name}" - end - - def username - (info.try(:nickname) || generate_username).to_s.force_encoding('utf-8') - end - - def email - (info.try(:email) || generate_temporarily_email).downcase - end - - def password - @password ||= Devise.friendly_token[0, 8].downcase - end - - # Get the first part of the email address (before @) - # In addtion in removes illegal characters - def generate_username - email.match(/^[^@]*/)[0].parameterize - end - - def generate_temporarily_email - "temp-email-for-oauth-#{username}@gitlab.localhost" - end - end - end -end diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb deleted file mode 100644 index 2f5c217d764992c0b06112a5c2b7ef76a50da7b3..0000000000000000000000000000000000000000 --- a/lib/gitlab/o_auth/user.rb +++ /dev/null @@ -1,106 +0,0 @@ -# OAuth extension for User model -# -# * Find GitLab user based on omniauth uid and provider -# * Create new user from omniauth data -# -module Gitlab - module OAuth - class ForbiddenAction < StandardError; end - - class User - attr_accessor :auth_hash, :gl_user - - def initialize(auth_hash) - self.auth_hash = auth_hash - end - - def persisted? - gl_user.try(:persisted?) - end - - def new? - !persisted? - end - - def valid? - gl_user.try(:valid?) - end - - def save - unauthorized_to_create unless gl_user - - if needs_blocking? - gl_user.save! - gl_user.block - else - gl_user.save! - end - - log.info "(OAuth) saving user #{auth_hash.email} from login with extern_uid => #{auth_hash.uid}" - gl_user - rescue ActiveRecord::RecordInvalid => e - log.info "(OAuth) Error saving user: #{gl_user.errors.full_messages}" - return self, e.record.errors - end - - def gl_user - @user ||= find_by_uid_and_provider - - if signup_enabled? - @user ||= build_new_user - end - - @user - end - - protected - - def needs_blocking? - new? && block_after_signup? - end - - def signup_enabled? - Gitlab.config.omniauth.allow_single_sign_on - end - - def block_after_signup? - Gitlab.config.omniauth.block_auto_created_users - end - - def auth_hash=(auth_hash) - @auth_hash = AuthHash.new(auth_hash) - end - - def find_by_uid_and_provider - identity = Identity.find_by(provider: auth_hash.provider, extern_uid: auth_hash.uid) - identity && identity.user - end - - def build_new_user - user = ::User.new(user_attributes) - user.skip_confirmation! - user.identities.new(extern_uid: auth_hash.uid, provider: auth_hash.provider) - user - end - - def user_attributes - { - name: auth_hash.name, - username: ::Namespace.clean_path(auth_hash.username), - email: auth_hash.email, - password: auth_hash.password, - password_confirmation: auth_hash.password, - password_automatically_set: true - } - end - - def log - Gitlab::AppLogger - end - - def unauthorized_to_create - raise ForbiddenAction.new("Unauthorized to create user, signup disabled for #{auth_hash.provider}") - end - end - end -end diff --git a/lib/gitlab/popen.rb b/lib/gitlab/popen.rb deleted file mode 100644 index 43e07e0916045d84d4587cfa35b7ec34aa9ba9db..0000000000000000000000000000000000000000 --- a/lib/gitlab/popen.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'fileutils' -require 'open3' - -module Gitlab - module Popen - extend self - - def popen(cmd, path=nil) - unless cmd.is_a?(Array) - raise "System commands must be given as an array of strings" - end - - path ||= Dir.pwd - vars = { "PWD" => path } - options = { chdir: path } - - unless File.directory?(path) - FileUtils.mkdir_p(path) - end - - @cmd_output = "" - @cmd_status = 0 - Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| - # We are not using stdin so we should close it, in case the command we - # are running waits for input. - stdin.close - @cmd_output << stdout.read - @cmd_output << stderr.read - @cmd_status = wait_thr.value.exitstatus - end - - [@cmd_output, @cmd_status] - end - end -end diff --git a/lib/gitlab/production_logger.rb b/lib/gitlab/production_logger.rb deleted file mode 100644 index 89ce7144b1bce57881ac850ee8cbfbfdcc250adb..0000000000000000000000000000000000000000 --- a/lib/gitlab/production_logger.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Gitlab - class ProductionLogger < Gitlab::Logger - def self.file_name_noext - 'production' - end - end -end diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb deleted file mode 100644 index 0dab7bcfa4d0c9af1081042fdd3121bdb924b779..0000000000000000000000000000000000000000 --- a/lib/gitlab/project_search_results.rb +++ /dev/null @@ -1,77 +0,0 @@ -module Gitlab - class ProjectSearchResults < SearchResults - attr_reader :project, :repository_ref - - def initialize(project_id, query, repository_ref = nil) - @project = Project.find(project_id) - @repository_ref = if repository_ref.present? - repository_ref - else - nil - end - @query = Shellwords.shellescape(query) if query.present? - end - - def objects(scope, page = nil) - case scope - when 'notes' - notes.page(page).per(per_page) - when 'blobs' - Kaminari.paginate_array(blobs).page(page).per(per_page) - when 'wiki_blobs' - Kaminari.paginate_array(wiki_blobs).page(page).per(per_page) - else - super - end - end - - def total_count - @total_count ||= issues_count + merge_requests_count + blobs_count + - notes_count + wiki_blobs_count - end - - def blobs_count - @blobs_count ||= blobs.count - end - - def notes_count - @notes_count ||= notes.count - end - - def wiki_blobs_count - @wiki_blobs_count ||= wiki_blobs.count - end - - private - - def blobs - if project.empty_repo? || query.blank? - [] - else - project.repository.search_files(query, repository_ref) - end - end - - def wiki_blobs - if project.wiki_enabled? && query.present? - project_wiki = ProjectWiki.new(project) - - unless project_wiki.empty? - project_wiki.search_files(query) - else - [] - end - else - [] - end - end - - def notes - Note.where(project_id: limit_project_ids).user.search(query).order('updated_at DESC') - end - - def limit_project_ids - [project.id] - end - end -end diff --git a/lib/gitlab/push_data_builder.rb b/lib/gitlab/push_data_builder.rb deleted file mode 100644 index f8da452e4c07cf676294419fa044679095020cbe..0000000000000000000000000000000000000000 --- a/lib/gitlab/push_data_builder.rb +++ /dev/null @@ -1,90 +0,0 @@ -module Gitlab - class PushDataBuilder - class << self - # Produce a hash of post-receive data - # - # data = { - # before: String, - # after: String, - # ref: String, - # user_id: String, - # user_name: String, - # user_email: String - # project_id: String, - # repository: { - # name: String, - # url: String, - # description: String, - # homepage: String, - # }, - # commits: Array, - # total_commits_count: Fixnum - # } - # - def build(project, user, oldrev, newrev, ref, commits = [], message = nil) - # Total commits count - commits_count = commits.size - - # Get latest 20 commits ASC - commits_limited = commits.last(20) - - # For performance purposes maximum 20 latest commits - # will be passed as post receive hook data. - commit_attrs = commits_limited.map do |commit| - commit.hook_attrs(project) - end - - type = Gitlab::Git.tag_ref?(ref) ? "tag_push" : "push" - # Hash to be passed as post_receive_data - data = { - object_kind: type, - before: oldrev, - after: newrev, - ref: ref, - checkout_sha: checkout_sha(project.repository, newrev, ref), - message: message, - user_id: user.id, - user_name: user.name, - user_email: user.email, - project_id: project.id, - repository: { - name: project.name, - url: project.url_to_repo, - description: project.description, - homepage: project.web_url, - git_http_url: project.http_url_to_repo, - git_ssh_url: project.ssh_url_to_repo, - visibility_level: project.visibility_level - }, - commits: commit_attrs, - total_commits_count: commits_count - } - - data - end - - # This method provide a sample data generated with - # existing project and commits to test web hooks - def build_sample(project, user) - commits = project.repository.commits(project.default_branch, nil, 3) - ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}#{project.default_branch}" - build(project, user, commits.last.id, commits.first.id, ref, commits) - end - - def checkout_sha(repository, newrev, ref) - # Find sha for tag, except when it was deleted. - if Gitlab::Git.tag_ref?(ref) && !Gitlab::Git.blank_ref?(newrev) - tag_name = Gitlab::Git.ref_name(ref) - tag = repository.find_tag(tag_name) - - if tag - commit = repository.commit(tag.target) - commit.try(:sha) - end - else - newrev - end - end - end - end -end diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb deleted file mode 100644 index a502a8fe9cd0ec0ffa751c1224843cc581e80ded..0000000000000000000000000000000000000000 --- a/lib/gitlab/reference_extractor.rb +++ /dev/null @@ -1,94 +0,0 @@ -module Gitlab - # Extract possible GFM references from an arbitrary String for further processing. - class ReferenceExtractor - attr_accessor :project, :current_user, :references - - include ::Gitlab::Markdown - - def initialize(project, current_user = nil) - @project = project - @current_user = current_user - end - - def can?(user, action, subject) - Ability.abilities.allowed?(user, action, subject) - end - - def analyze(text) - text = text.dup - - # Remove preformatted/code blocks so that references are not included - text.gsub!(%r{
    .*?
    |.*?}m) { |match| '' } - text.gsub!(%r{^```.*?^```}m) { |match| '' } - - @references = Hash.new { |hash, type| hash[type] = [] } - parse_references(text) - end - - # Given a valid project, resolve the extracted identifiers of the requested type to - # model objects. - - def users - references[:user].uniq.map do |project, identifier| - if identifier == "all" - project.team.members.flatten - elsif namespace = Namespace.find_by(path: identifier) - if namespace.is_a?(Group) - namespace.users - else - namespace.owner - end - end - end.flatten.compact.uniq - end - - def labels - references[:label].uniq.map do |project, identifier| - project.labels.where(id: identifier).first - end.compact.uniq - end - - def issues - references[:issue].uniq.map do |project, identifier| - if project.default_issues_tracker? - project.issues.where(iid: identifier).first - end - end.compact.uniq - end - - def merge_requests - references[:merge_request].uniq.map do |project, identifier| - project.merge_requests.where(iid: identifier).first - end.compact.uniq - end - - def snippets - references[:snippet].uniq.map do |project, identifier| - project.snippets.where(id: identifier).first - end.compact.uniq - end - - def commits - references[:commit].uniq.map do |project, identifier| - repo = project.repository - repo.commit(identifier) if repo - end.compact.uniq - end - - def commit_ranges - references[:commit_range].uniq.map do |project, identifier| - repo = project.repository - if repo - from_id, to_id = identifier.split(/\.{2,3}/, 2) - [repo.commit(from_id), repo.commit(to_id)] - end - end.compact.uniq - end - - private - - def reference_link(type, identifier, project, _) - references[type] << [project, identifier] - end - end -end diff --git a/lib/gitlab/satellite/action.rb b/lib/gitlab/satellite/action.rb deleted file mode 100644 index 4890ccf21e6338672f4e397427eda69e7e3fd87a..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/action.rb +++ /dev/null @@ -1,56 +0,0 @@ -module Gitlab - module Satellite - class Action - DEFAULT_OPTIONS = { git_timeout: Gitlab.config.satellites.timeout.seconds } - - attr_accessor :options, :project, :user - - def initialize(user, project, options = {}) - @options = DEFAULT_OPTIONS.merge(options) - @project = project - @user = user - end - - protected - - # * Sets a 30s timeout for Git - # * Locks the satellite repo - # * Yields the prepared satellite repo - def in_locked_and_timed_satellite - Gitlab::ShellEnv.set_env(user) - - Grit::Git.with_timeout(options[:git_timeout]) do - project.satellite.lock do - return yield project.satellite.repo - end - end - rescue Errno::ENOMEM => ex - return handle_exception(ex) - rescue Grit::Git::GitTimeout => ex - return handle_exception(ex) - ensure - Gitlab::ShellEnv.reset_env - end - - # * Recreates the satellite - # * Sets up Git variables for the user - # - # Note: use this within #in_locked_and_timed_satellite - def prepare_satellite!(repo) - project.satellite.clear_and_update! - - repo.config['user.name'] = user.name - repo.config['user.email'] = user.email - end - - def default_options(options = {}) - { raise: true, timeout: true }.merge(options) - end - - def handle_exception(exception) - Gitlab::GitLogger.error(exception.message) - false - end - end - end -end diff --git a/lib/gitlab/satellite/compare_action.rb b/lib/gitlab/satellite/compare_action.rb deleted file mode 100644 index 46c98a8f4cab479a6bfa2f5ee6483864403fd807..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/compare_action.rb +++ /dev/null @@ -1,44 +0,0 @@ -module Gitlab - module Satellite - class BranchesWithoutParent < StandardError; end - - class CompareAction < Action - def initialize(user, target_project, target_branch, source_project, source_branch) - super user, target_project - - @target_project, @target_branch = target_project, target_branch - @source_project, @source_branch = source_project, source_branch - end - - # Compare 2 repositories and return Gitlab::CompareResult object - def result - in_locked_and_timed_satellite do |target_repo| - prepare_satellite!(target_repo) - update_satellite_source_and_target!(target_repo) - - Gitlab::CompareResult.new(compare(target_repo)) - end - rescue Grit::Git::CommandFailed => ex - raise BranchesWithoutParent - end - - private - - # Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for diffs - def update_satellite_source_and_target!(target_repo) - target_repo.remote_add('source', @source_project.repository.path_to_repo) - target_repo.remote_fetch('source') - rescue Grit::Git::CommandFailed => ex - handle_exception(ex) - end - - def compare(repo) - @compare ||= Gitlab::Git::Compare.new( - Gitlab::Git::Repository.new(repo.path), - "origin/#{@target_branch}", - "source/#{@source_branch}" - ) - end - end - end -end diff --git a/lib/gitlab/satellite/files/delete_file_action.rb b/lib/gitlab/satellite/files/delete_file_action.rb deleted file mode 100644 index 0d37b9dea8502e765aed57cfedfea514f29dcc9e..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/files/delete_file_action.rb +++ /dev/null @@ -1,50 +0,0 @@ -require_relative 'file_action' - -module Gitlab - module Satellite - class DeleteFileAction < FileAction - # Deletes file and creates a new commit for it - # - # Returns false if committing the change fails - # Returns false if pushing from the satellite to bare repo failed or was rejected - # Returns true otherwise - def commit!(content, commit_message) - in_locked_and_timed_satellite do |repo| - prepare_satellite!(repo) - - # create target branch in satellite at the corresponding commit from bare repo - repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}") - - # update the file in the satellite's working dir - file_path_in_satellite = File.join(repo.working_dir, file_path) - - # Prevent relative links - unless safe_path?(file_path_in_satellite) - Gitlab::GitLogger.error("FileAction: Relative path not allowed") - return false - end - - File.delete(file_path_in_satellite) - - # add removed file - repo.remove(file_path_in_satellite) - - # commit the changes - # will raise CommandFailed when commit fails - repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) - - - # push commit back to bare repo - # will raise CommandFailed when push fails - repo.git.push({ raise: true, timeout: true }, :origin, ref) - - # everything worked - true - end - rescue Grit::Git::CommandFailed => ex - Gitlab::GitLogger.error(ex.message) - false - end - end - end -end diff --git a/lib/gitlab/satellite/files/edit_file_action.rb b/lib/gitlab/satellite/files/edit_file_action.rb deleted file mode 100644 index 3cb9c0b5ecbceed9529812162d235befca60ffb7..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/files/edit_file_action.rb +++ /dev/null @@ -1,68 +0,0 @@ -require_relative 'file_action' - -module Gitlab - module Satellite - # GitLab server-side file update and commit - class EditFileAction < FileAction - # Updates the files content and creates a new commit for it - # - # Returns false if the ref has been updated while editing the file - # Returns false if committing the change fails - # Returns false if pushing from the satellite to bare repo failed or was rejected - # Returns true otherwise - def commit!(content, commit_message, encoding, new_branch = nil) - in_locked_and_timed_satellite do |repo| - prepare_satellite!(repo) - - # create target branch in satellite at the corresponding commit from bare repo - begin - repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}") - rescue Grit::Git::CommandFailed => ex - log_and_raise(CheckoutFailed, ex.message) - end - - # update the file in the satellite's working dir - file_path_in_satellite = File.join(repo.working_dir, file_path) - - # Prevent relative links - unless safe_path?(file_path_in_satellite) - Gitlab::GitLogger.error("FileAction: Relative path not allowed") - return false - end - - # Write file - write_file(file_path_in_satellite, content, encoding) - - # commit the changes - # will raise CommandFailed when commit fails - begin - repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) - rescue Grit::Git::CommandFailed => ex - log_and_raise(CommitFailed, ex.message) - end - - - target_branch = new_branch.present? ? "#{ref}:#{new_branch}" : ref - - # push commit back to bare repo - # will raise CommandFailed when push fails - begin - repo.git.push({ raise: true, timeout: true }, :origin, target_branch) - rescue Grit::Git::CommandFailed => ex - log_and_raise(PushFailed, ex.message) - end - - # everything worked - true - end - end - - private - - def log_and_raise(errorClass, message) - Gitlab::GitLogger.error(message) - raise(errorClass, message) - end - end - end -end diff --git a/lib/gitlab/satellite/files/file_action.rb b/lib/gitlab/satellite/files/file_action.rb deleted file mode 100644 index 6446b14568a5de087d3e0cbbf91506dacf24fa74..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/files/file_action.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Gitlab - module Satellite - class FileAction < Action - attr_accessor :file_path, :ref - - def initialize(user, project, ref, file_path) - super user, project - @file_path = file_path - @ref = ref - end - - def safe_path?(path) - File.absolute_path(path) == path - end - - def write_file(abs_file_path, content, file_encoding = 'text') - if file_encoding == 'base64' - File.open(abs_file_path, 'wb') { |f| f.write(Base64.decode64(content)) } - else - File.open(abs_file_path, 'w') { |f| f.write(content) } - end - end - end - end -end diff --git a/lib/gitlab/satellite/files/new_file_action.rb b/lib/gitlab/satellite/files/new_file_action.rb deleted file mode 100644 index 724dfa0d042e1a80376a40dad4a34967998fdf5e..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/files/new_file_action.rb +++ /dev/null @@ -1,67 +0,0 @@ -require_relative 'file_action' - -module Gitlab - module Satellite - class NewFileAction < FileAction - # Updates the files content and creates a new commit for it - # - # Returns false if the ref has been updated while editing the file - # Returns false if committing the change fails - # Returns false if pushing from the satellite to bare repo failed or was rejected - # Returns true otherwise - def commit!(content, commit_message, encoding, new_branch = nil) - in_locked_and_timed_satellite do |repo| - prepare_satellite!(repo) - - # create target branch in satellite at the corresponding commit from bare repo - current_ref = - if @project.empty_repo? - # skip this step if we want to add first file to empty repo - Satellite::PARKING_BRANCH - else - repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}") - ref - end - - file_path_in_satellite = File.join(repo.working_dir, file_path) - dir_name_in_satellite = File.dirname(file_path_in_satellite) - - # Prevent relative links - unless safe_path?(file_path_in_satellite) - Gitlab::GitLogger.error("FileAction: Relative path not allowed") - return false - end - - # Create dir if not exists - FileUtils.mkdir_p(dir_name_in_satellite) - - # Write file - write_file(file_path_in_satellite, content, encoding) - - # add new file - repo.add(file_path_in_satellite) - - # commit the changes - # will raise CommandFailed when commit fails - repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) - - target_branch = if new_branch.present? && !@project.empty_repo? - "#{ref}:#{new_branch}" - else - "#{current_ref}:#{ref}" - end - - # push commit back to bare repo - # will raise CommandFailed when push fails - repo.git.push({ raise: true, timeout: true }, :origin, target_branch) - - # everything worked - true - end - rescue Grit::Git::CommandFailed => ex - Gitlab::GitLogger.error(ex.message) - false - end - end - end -end diff --git a/lib/gitlab/satellite/logger.rb b/lib/gitlab/satellite/logger.rb deleted file mode 100644 index 6f3f8255aca11e5b9c77bf98bd968a299e3c9756..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/logger.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Gitlab - module Satellite - class Logger < Gitlab::Logger - def self.file_name - 'satellites.log' - end - - def format_message(severity, timestamp, progname, msg) - "#{timestamp.to_s(:long)}: #{msg}\n" - end - end - end -end diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb deleted file mode 100644 index 1f2e5f82dd5348017eba0fa9385ef0e38357907a..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/merge_action.rb +++ /dev/null @@ -1,146 +0,0 @@ -module Gitlab - module Satellite - # GitLab server-side merge - class MergeAction < Action - attr_accessor :merge_request - - def initialize(user, merge_request) - super user, merge_request.target_project - @merge_request = merge_request - end - - # Checks if a merge request can be executed without user interaction - def can_be_merged? - in_locked_and_timed_satellite do |merge_repo| - prepare_satellite!(merge_repo) - merge_in_satellite!(merge_repo) - end - end - - # Merges the source branch into the target branch in the satellite and - # pushes it back to the repository. - # It also removes the source branch if requested in the merge request (and this is permitted by the merge request). - # - # Returns false if the merge produced conflicts - # Returns false if pushing from the satellite to the repository failed or was rejected - # Returns true otherwise - def merge!(merge_commit_message = nil) - in_locked_and_timed_satellite do |merge_repo| - prepare_satellite!(merge_repo) - if merge_in_satellite!(merge_repo, merge_commit_message) - # push merge back to bare repo - # will raise CommandFailed when push fails - merge_repo.git.push(default_options, :origin, merge_request.target_branch) - - # remove source branch - if merge_request.should_remove_source_branch && !project.root_ref?(merge_request.source_branch) && !merge_request.for_fork? - # will raise CommandFailed when push fails - merge_repo.git.push(default_options, :origin, ":#{merge_request.source_branch}") - end - # merge, push and branch removal successful - true - end - end - rescue Grit::Git::CommandFailed => ex - handle_exception(ex) - end - - def diff_in_satellite - in_locked_and_timed_satellite do |merge_repo| - prepare_satellite!(merge_repo) - update_satellite_source_and_target!(merge_repo) - - # Only show what is new in the source branch compared to the target branch, not the other way around. - # The line below with merge_base is equivalent to diff with three dots (git diff branch1...branch2) - # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B" - common_commit = merge_repo.git.native(:merge_base, default_options, ["origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}"]).strip - merge_repo.git.native(:diff, default_options, common_commit, "source/#{merge_request.source_branch}") - end - rescue Grit::Git::CommandFailed => ex - handle_exception(ex) - end - - def diffs_between_satellite - in_locked_and_timed_satellite do |merge_repo| - prepare_satellite!(merge_repo) - update_satellite_source_and_target!(merge_repo) - if merge_request.for_fork? - repository = Gitlab::Git::Repository.new(merge_repo.path) - diffs = Gitlab::Git::Diff.between( - repository, - "source/#{merge_request.source_branch}", - "origin/#{merge_request.target_branch}" - ) - else - raise "Attempt to determine diffs between for a non forked merge request in satellite MergeRequest.id:[#{merge_request.id}]" - end - - return diffs - end - rescue Grit::Git::CommandFailed => ex - handle_exception(ex) - end - - # Get commit as an email patch - def format_patch - in_locked_and_timed_satellite do |merge_repo| - prepare_satellite!(merge_repo) - update_satellite_source_and_target!(merge_repo) - patch = merge_repo.git.format_patch(default_options({ stdout: true }), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}") - end - rescue Grit::Git::CommandFailed => ex - handle_exception(ex) - end - - # Retrieve an array of commits between the source and the target - def commits_between - in_locked_and_timed_satellite do |merge_repo| - prepare_satellite!(merge_repo) - update_satellite_source_and_target!(merge_repo) - if merge_request.for_fork? - repository = Gitlab::Git::Repository.new(merge_repo.path) - commits = Gitlab::Git::Commit.between( - repository, - "origin/#{merge_request.target_branch}", - "source/#{merge_request.source_branch}" - ) - else - raise "Attempt to determine commits between for a non forked merge request in satellite MergeRequest.id:[#{merge_request.id}]" - end - - return commits - end - rescue Grit::Git::CommandFailed => ex - handle_exception(ex) - end - - private - # Merges the source_branch into the target_branch in the satellite. - # - # Note: it will clear out the satellite before doing anything - # - # Returns false if the merge produced conflicts - # Returns true otherwise - def merge_in_satellite!(repo, message = nil) - update_satellite_source_and_target!(repo) - - message ||= "Merge branch '#{merge_request.source_branch}' into '#{merge_request.target_branch}'" - - # merge the source branch into the satellite - # will raise CommandFailed when merge fails - repo.git.merge(default_options({ no_ff: true }), "-m#{message}", "source/#{merge_request.source_branch}") - rescue Grit::Git::CommandFailed => ex - handle_exception(ex) - end - - # Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for merges, diffs etc - def update_satellite_source_and_target!(repo) - repo.remote_add('source', merge_request.source_project.repository.path_to_repo) - repo.remote_fetch('source') - repo.git.checkout(default_options({ b: true }), merge_request.target_branch, "origin/#{merge_request.target_branch}") - rescue Grit::Git::CommandFailed => ex - handle_exception(ex) - end - end - end -end diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb deleted file mode 100644 index 398643d68de2c07a56ba30181786f693dae6219a..0000000000000000000000000000000000000000 --- a/lib/gitlab/satellite/satellite.rb +++ /dev/null @@ -1,148 +0,0 @@ -module Gitlab - module Satellite - autoload :DeleteFileAction, 'gitlab/satellite/files/delete_file_action' - autoload :EditFileAction, 'gitlab/satellite/files/edit_file_action' - autoload :FileAction, 'gitlab/satellite/files/file_action' - autoload :NewFileAction, 'gitlab/satellite/files/new_file_action' - - class CheckoutFailed < StandardError; end - class CommitFailed < StandardError; end - class PushFailed < StandardError; end - - class Satellite - include Gitlab::Popen - - PARKING_BRANCH = "__parking_branch" - - attr_accessor :project - - def initialize(project) - @project = project - end - - def log(message) - Gitlab::Satellite::Logger.error(message) - end - - def clear_and_update! - project.ensure_satellite_exists - - @repo = nil - clear_working_dir! - delete_heads! - remove_remotes! - update_from_source! - end - - def create - output, status = popen(%W(git clone -- #{project.repository.path_to_repo} #{path}), - Gitlab.config.satellites.path) - - log("PID: #{project.id}: git clone #{project.repository.path_to_repo} #{path}") - log("PID: #{project.id}: -> #{output}") - - if status.zero? - true - else - log("Failed to create satellite for #{project.name_with_namespace}") - false - end - end - - def exists? - File.exists? path - end - - # * Locks the satellite - # * Changes the current directory to the satellite's working dir - # * Yields - def lock - project.ensure_satellite_exists - - File.open(lock_file, "w+") do |f| - begin - f.flock File::LOCK_EX - yield - ensure - f.flock File::LOCK_UN - end - end - end - - def lock_file - create_locks_dir unless File.exists?(lock_files_dir) - File.join(lock_files_dir, "satellite_#{project.id}.lock") - end - - def path - File.join(Gitlab.config.satellites.path, project.path_with_namespace) - end - - def repo - project.ensure_satellite_exists - - @repo ||= Grit::Repo.new(path) - end - - def destroy - FileUtils.rm_rf(path) - end - - private - - # Clear the working directory - def clear_working_dir! - repo.git.reset(hard: true) - repo.git.clean(f: true, d: true, x: true) - end - - # Deletes all branches except the parking branch - # - # This ensures we have no name clashes or issues updating branches when - # working with the satellite. - def delete_heads! - heads = repo.heads.map(&:name) - - # update or create the parking branch - repo.git.checkout(default_options({ B: true }), PARKING_BRANCH) - - # remove the parking branch from the list of heads ... - heads.delete(PARKING_BRANCH) - # ... and delete all others - heads.each { |head| repo.git.branch(default_options({ D: true }), head) } - end - - # Deletes all remotes except origin - # - # This ensures we have no remote name clashes or issues updating branches when - # working with the satellite. - def remove_remotes! - remotes = repo.git.remote.split(' ') - remotes.delete('origin') - remotes.each { |name| repo.git.remote(default_options,'rm', name)} - end - - # Updates the satellite from bare repo - # - # Note: this will only update remote branches (i.e. origin/*) - def update_from_source! - repo.git.remote(default_options, 'set-url', :origin, project.repository.path_to_repo) - repo.git.fetch(default_options, :origin) - end - - def default_options(options = {}) - { raise: true, timeout: true }.merge(options) - end - - # Create directory for storing - # satellites lock files - def create_locks_dir - FileUtils.mkdir_p(lock_files_dir) - end - - def lock_files_dir - @lock_files_dir ||= File.join(Gitlab.config.satellites.path, "tmp") - end - end - end -end diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb deleted file mode 100644 index 75a3dfe37c3931262b1016d1102c704ea2c17f46..0000000000000000000000000000000000000000 --- a/lib/gitlab/search_results.rb +++ /dev/null @@ -1,69 +0,0 @@ -module Gitlab - class SearchResults - attr_reader :query - - # Limit search results by passed project ids - # It allows us to search only for projects user has access to - attr_reader :limit_project_ids - - def initialize(limit_project_ids, query) - @limit_project_ids = limit_project_ids || Project.all - @query = Shellwords.shellescape(query) if query.present? - end - - def objects(scope, page = nil) - case scope - when 'projects' - projects.page(page).per(per_page) - when 'issues' - issues.page(page).per(per_page) - when 'merge_requests' - merge_requests.page(page).per(per_page) - else - Kaminari.paginate_array([]).page(page).per(per_page) - end - end - - def total_count - @total_count ||= projects_count + issues_count + merge_requests_count - end - - def projects_count - @projects_count ||= projects.count - end - - def issues_count - @issues_count ||= issues.count - end - - def merge_requests_count - @merge_requests_count ||= merge_requests.count - end - - def empty? - total_count.zero? - end - - private - - def projects - Project.where(id: limit_project_ids).search(query) - end - - def issues - Issue.where(project_id: limit_project_ids).full_search(query).order('updated_at DESC') - end - - def merge_requests - MergeRequest.in_projects(limit_project_ids).full_search(query).order('updated_at DESC') - end - - def default_scope - 'projects' - end - - def per_page - 20 - end - end -end diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb deleted file mode 100644 index 31aa3528c4c37a4aa4416da61e6d0df01368b9c0..0000000000000000000000000000000000000000 --- a/lib/gitlab/seeder.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Gitlab - class Seeder - def self.quiet - mute_mailer - SeedFu.quiet = true - yield - SeedFu.quiet = false - puts "\nOK".green - end - - def self.by_user(user) - yield - end - - def self.mute_mailer - code = <<-eos -def Notify.delay - self -end - eos - eval(code) - end - end -end diff --git a/lib/gitlab/sidekiq_logger.rb b/lib/gitlab/sidekiq_logger.rb deleted file mode 100644 index c1dab87a43231c56ebe3ee01e9788771158ace90..0000000000000000000000000000000000000000 --- a/lib/gitlab/sidekiq_logger.rb +++ /dev/null @@ -1,7 +0,0 @@ -module Gitlab - class SidekiqLogger < Gitlab::Logger - def self.file_name_noext - 'sidekiq' - end - end -end diff --git a/lib/gitlab/sidekiq_middleware/arguments_logger.rb b/lib/gitlab/sidekiq_middleware/arguments_logger.rb deleted file mode 100644 index 7813091ec7b44f8b74d647d4417183819493f363..0000000000000000000000000000000000000000 --- a/lib/gitlab/sidekiq_middleware/arguments_logger.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Gitlab - module SidekiqMiddleware - class ArgumentsLogger - def call(worker, job, queue) - Sidekiq.logger.info "arguments: #{job['args']}" - yield - end - end - end -end diff --git a/lib/gitlab/sidekiq_middleware/memory_killer.rb b/lib/gitlab/sidekiq_middleware/memory_killer.rb deleted file mode 100644 index 0f2db50e98c9625c28a6db405c36e94656cfb988..0000000000000000000000000000000000000000 --- a/lib/gitlab/sidekiq_middleware/memory_killer.rb +++ /dev/null @@ -1,53 +0,0 @@ -module Gitlab - module SidekiqMiddleware - class MemoryKiller - # Default the RSS limit to 0, meaning the MemoryKiller is disabled - MAX_RSS = (ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS'] || 0).to_s.to_i - # Give Sidekiq 15 minutes of grace time after exceeding the RSS limit - GRACE_TIME = (ENV['SIDEKIQ_MEMORY_KILLER_GRACE_TIME'] || 15 * 60).to_s.to_i - # Wait 30 seconds for running jobs to finish during graceful shutdown - SHUTDOWN_WAIT = (ENV['SIDEKIQ_MEMORY_KILLER_SHUTDOWN_WAIT'] || 30).to_s.to_i - - # Create a mutex used to ensure there will be only one thread waiting to - # shut Sidekiq down - MUTEX = Mutex.new - - def call(worker, job, queue) - yield - current_rss = get_rss - - return unless MAX_RSS > 0 && current_rss > MAX_RSS - - Thread.new do - # Return if another thread is already waiting to shut Sidekiq down - return unless MUTEX.try_lock - - Sidekiq.logger.warn "current RSS #{current_rss} exceeds maximum RSS "\ - "#{MAX_RSS}" - Sidekiq.logger.warn "spawned thread that will shut down PID "\ - "#{Process.pid} in #{GRACE_TIME} seconds" - sleep(GRACE_TIME) - - Sidekiq.logger.warn "sending SIGUSR1 to PID #{Process.pid}" - Process.kill('SIGUSR1', Process.pid) - - Sidekiq.logger.warn "waiting #{SHUTDOWN_WAIT} seconds before sending "\ - "SIGTERM to PID #{Process.pid}" - sleep(SHUTDOWN_WAIT) - - Sidekiq.logger.warn "sending SIGTERM to PID #{Process.pid}" - Process.kill('SIGTERM', Process.pid) - end - end - - private - - def get_rss - output, status = Gitlab::Popen.popen(%W(ps -o rss= -p #{Process.pid})) - return 0 unless status.zero? - - output.to_i - end - end - end -end diff --git a/lib/gitlab/snippet_search_results.rb b/lib/gitlab/snippet_search_results.rb deleted file mode 100644 index 938219efdb29d6cf75e2d84dad062e7a267243ec..0000000000000000000000000000000000000000 --- a/lib/gitlab/snippet_search_results.rb +++ /dev/null @@ -1,131 +0,0 @@ -module Gitlab - class SnippetSearchResults < SearchResults - attr_reader :limit_snippet_ids - - def initialize(limit_snippet_ids, query) - @limit_snippet_ids = limit_snippet_ids - @query = query - end - - def objects(scope, page = nil) - case scope - when 'snippet_titles' - Kaminari.paginate_array(snippet_titles).page(page).per(per_page) - when 'snippet_blobs' - Kaminari.paginate_array(snippet_blobs).page(page).per(per_page) - else - super - end - end - - def total_count - @total_count ||= snippet_titles_count + snippet_blobs_count - end - - def snippet_titles_count - @snippet_titles_count ||= snippet_titles.count - end - - def snippet_blobs_count - @snippet_blobs_count ||= snippet_blobs.count - end - - private - - def snippet_titles - Snippet.where(id: limit_snippet_ids).search(query).order('updated_at DESC') - end - - def snippet_blobs - search = Snippet.where(id: limit_snippet_ids).search_code(query) - search = search.order('updated_at DESC').to_a - snippets = [] - search.each { |e| snippets << chunk_snippet(e) } - snippets - end - - def default_scope - 'snippet_blobs' - end - - # Get an array of line numbers surrounding a matching - # line, bounded by min/max. - # - # @returns Array of line numbers - def bounded_line_numbers(line, min, max) - lower = line - surrounding_lines > min ? line - surrounding_lines : min - upper = line + surrounding_lines < max ? line + surrounding_lines : max - (lower..upper).to_a - end - - # Returns a sorted set of lines to be included in a snippet preview. - # This ensures matching adjacent lines do not display duplicated - # surrounding code. - # - # @returns Array, unique and sorted. - def matching_lines(lined_content) - used_lines = [] - lined_content.each_with_index do |line, line_number| - used_lines.concat bounded_line_numbers( - line_number, - 0, - lined_content.size - ) if line.include?(query) - end - - used_lines.uniq.sort - end - - # 'Chunkify' entire snippet. Splits the snippet data into matching lines + - # surrounding_lines() worth of unmatching lines. - # - # @returns a hash with {snippet_object, snippet_chunks:{data,start_line}} - def chunk_snippet(snippet) - lined_content = snippet.content.split("\n") - used_lines = matching_lines(lined_content) - - snippet_chunk = [] - snippet_chunks = [] - snippet_start_line = 0 - last_line = -1 - - # Go through each used line, and add consecutive lines as a single chunk - # to the snippet chunk array. - used_lines.each do |line_number| - if last_line < 0 - # Start a new chunk. - snippet_start_line = line_number - snippet_chunk << lined_content[line_number] - elsif last_line == line_number - 1 - # Consecutive line, continue chunk. - snippet_chunk << lined_content[line_number] - else - # Non-consecutive line, add chunk to chunk array. - snippet_chunks << { - data: snippet_chunk.join("\n"), - start_line: snippet_start_line + 1 - } - - # Start a new chunk. - snippet_chunk = [lined_content[line_number]] - snippet_start_line = line_number - end - last_line = line_number - end - # Add final chunk to chunk array - snippet_chunks << { - data: snippet_chunk.join("\n"), - start_line: snippet_start_line + 1 - } - - # Return snippet with chunk array - { snippet_object: snippet, snippet_chunks: snippet_chunks } - end - - # Defines how many unmatching lines should be - # included around the matching lines in a snippet - def surrounding_lines - 3 - end - end -end diff --git a/lib/gitlab/theme.rb b/lib/gitlab/theme.rb deleted file mode 100644 index 43093c7d27ebbf804adef24176611b0a31ed6075..0000000000000000000000000000000000000000 --- a/lib/gitlab/theme.rb +++ /dev/null @@ -1,39 +0,0 @@ -module Gitlab - class Theme - BASIC = 1 unless const_defined?(:BASIC) - MARS = 2 unless const_defined?(:MARS) - MODERN = 3 unless const_defined?(:MODERN) - GRAY = 4 unless const_defined?(:GRAY) - COLOR = 5 unless const_defined?(:COLOR) - BLUE = 6 unless const_defined?(:BLUE) - - def self.css_class_by_id(id) - themes = { - BASIC => "ui_basic", - MARS => "ui_mars", - MODERN => "ui_modern", - GRAY => "ui_gray", - COLOR => "ui_color", - BLUE => "ui_blue" - } - - id ||= Gitlab.config.gitlab.default_theme - - themes[id] - end - - def self.type_css_class_by_id(id) - types = { - BASIC => 'light_theme', - MARS => 'dark_theme', - MODERN => 'dark_theme', - GRAY => 'dark_theme', - COLOR => 'dark_theme' - } - - id ||= Gitlab.config.gitlab.default_theme - - types[id] - end - end -end diff --git a/lib/gitlab/upgrader.rb b/lib/gitlab/upgrader.rb deleted file mode 100644 index 0570c2fbeb53c11d0e091636ac18d02138c8a22d..0000000000000000000000000000000000000000 --- a/lib/gitlab/upgrader.rb +++ /dev/null @@ -1,102 +0,0 @@ -require_relative "popen" -require_relative "version_info" - -module Gitlab - class Upgrader - def execute - puts "GitLab #{current_version.major} upgrade tool" - puts "Your version is #{current_version}" - puts "Latest available version for GitLab #{current_version.major} is #{latest_version}" - - if latest_version? - puts "You are using the latest GitLab version" - else - puts "Newer GitLab version is available" - answer = if ARGV.first == "-y" - "yes" - else - prompt("Do you want to upgrade (yes/no)? ", %w{yes no}) - end - - if answer == "yes" - upgrade - else - exit 0 - end - end - end - - def latest_version? - current_version >= latest_version - end - - def current_version - @current_version ||= Gitlab::VersionInfo.parse(current_version_raw) - end - - def latest_version - @latest_version ||= Gitlab::VersionInfo.parse(latest_version_raw) - end - - def current_version_raw - File.read(File.join(gitlab_path, "VERSION")).strip - end - - def latest_version_raw - remote_tags, _ = Gitlab::Popen.popen(%W(git ls-remote --tags https://gitlab.com/gitlab-org/gitlab-ce.git)) - git_tags = remote_tags.split("\n").grep(/tags\/v#{current_version.major}/) - git_tags = git_tags.select { |version| version =~ /v\d\.\d\.\d\Z/ } - last_tag = git_tags.last.match(/v\d\.\d\.\d/).to_s - end - - def update_commands - { - "Stash changed files" => %W(git stash), - "Get latest code" => %W(git fetch), - "Switch to new version" => %W(git checkout v#{latest_version}), - "Install gems" => %W(bundle), - "Migrate DB" => %W(bundle exec rake db:migrate), - "Recompile assets" => %W(bundle exec rake assets:clean assets:precompile), - "Clear cache" => %W(bundle exec rake cache:clear) - } - end - - def env - { 'RAILS_ENV' => 'production' } - end - - def upgrade - update_commands.each do |title, cmd| - puts title - puts " -> #{cmd.join(' ')}" - if system(env, *cmd) - puts " -> OK" - else - puts " -> FAILED" - puts "Failed to upgrade. Try to repeat task or proceed with upgrade manually " - exit 1 - end - end - - puts "Done" - end - - def gitlab_path - File.expand_path(File.join(File.dirname(__FILE__), '../..')) - end - - # Prompt the user to input something - # - # message - the message to display before input - # choices - array of strings of acceptable answers or nil for any answer - # - # Returns the user's answer - def prompt(message, choices = nil) - begin - print(message) - answer = STDIN.gets.chomp - end while !choices.include?(answer) - answer - end - end -end diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb deleted file mode 100644 index 11b0d44f34067e461f5410b16acd4081769e751e..0000000000000000000000000000000000000000 --- a/lib/gitlab/url_builder.rb +++ /dev/null @@ -1,60 +0,0 @@ -module Gitlab - class UrlBuilder - include Rails.application.routes.url_helpers - include GitlabRoutingHelper - - def initialize(type) - @type = type - end - - def build(id) - case @type - when :issue - build_issue_url(id) - when :merge_request - build_merge_request_url(id) - when :note - build_note_url(id) - - end - end - - private - - def build_issue_url(id) - issue = Issue.find(id) - issue_url(issue, host: Gitlab.config.gitlab['url']) - end - - def build_merge_request_url(id) - merge_request = MergeRequest.find(id) - merge_request_url(merge_request, host: Gitlab.config.gitlab['url']) - end - - def build_note_url(id) - note = Note.find(id) - if note.for_commit? - namespace_project_commit_url(namespace_id: note.project.namespace, - id: note.commit_id, - project_id: note.project, - host: Gitlab.config.gitlab['url'], - anchor: "note_#{note.id}") - elsif note.for_issue? - issue = Issue.find(note.noteable_id) - issue_url(issue, - host: Gitlab.config.gitlab['url'], - anchor: "note_#{note.id}") - elsif note.for_merge_request? - merge_request = MergeRequest.find(note.noteable_id) - merge_request_url(merge_request, - host: Gitlab.config.gitlab['url'], - anchor: "note_#{note.id}") - elsif note.for_project_snippet? - snippet = Snippet.find(note.noteable_id) - project_snippet_url(snippet, - host: Gitlab.config.gitlab['url'], - anchor: "note_#{note.id}") - end - end - end -end diff --git a/lib/gitlab/user_access.rb b/lib/gitlab/user_access.rb deleted file mode 100644 index 4885baf95265ff1a9d97b22c966c522452c25cf5..0000000000000000000000000000000000000000 --- a/lib/gitlab/user_access.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Gitlab - module UserAccess - def self.allowed?(user) - return false if user.blocked? - - if user.requires_ldap_check? - return false unless Gitlab::LDAP::Access.allowed?(user) - end - - true - end - end -end diff --git a/lib/gitlab/utils.rb b/lib/gitlab/utils.rb deleted file mode 100644 index bd184c271871e83519f2c847b1f38e1e261a2bf7..0000000000000000000000000000000000000000 --- a/lib/gitlab/utils.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Gitlab - module Utils - extend self - - # Run system command without outputting to stdout. - # - # @param cmd [Array] - # @return [Boolean] - def system_silent(cmd) - Popen::popen(cmd).last.zero? - end - end -end diff --git a/lib/gitlab/version_info.rb b/lib/gitlab/version_info.rb deleted file mode 100644 index 6ee41e85cc9bf33c10b690df09ca735b22f3790f..0000000000000000000000000000000000000000 --- a/lib/gitlab/version_info.rb +++ /dev/null @@ -1,54 +0,0 @@ -module Gitlab - class VersionInfo - include Comparable - - attr_reader :major, :minor, :patch - - def self.parse(str) - if str && m = str.match(/(\d+)\.(\d+)\.(\d+)/) - VersionInfo.new(m[1].to_i, m[2].to_i, m[3].to_i) - else - VersionInfo.new - end - end - - def initialize(major = 0, minor = 0, patch = 0) - @major = major - @minor = minor - @patch = patch - end - - def <=>(other) - return unless other.is_a? VersionInfo - return unless valid? && other.valid? - - if other.major < @major - 1 - elsif @major < other.major - -1 - elsif other.minor < @minor - 1 - elsif @minor < other.minor - -1 - elsif other.patch < @patch - 1 - elsif @patch < other.patch - -1 - else - 0 - end - end - - def to_s - if valid? - "%d.%d.%d" % [@major, @minor, @patch] - else - "Unknown" - end - end - - def valid? - @major >= 0 && @minor >= 0 && @patch >= 0 && @major + @minor + @patch > 0 - end - end -end diff --git a/lib/gitlab/visibility_level.rb b/lib/gitlab/visibility_level.rb deleted file mode 100644 index 582fc759efd2026ef45165b08c9c5541c6c11d54..0000000000000000000000000000000000000000 --- a/lib/gitlab/visibility_level.rb +++ /dev/null @@ -1,64 +0,0 @@ -# Gitlab::VisibilityLevel module -# -# Define allowed public modes that can be used for -# GitLab projects to determine project public mode -# -module Gitlab - module VisibilityLevel - extend CurrentSettings - - PRIVATE = 0 unless const_defined?(:PRIVATE) - INTERNAL = 10 unless const_defined?(:INTERNAL) - PUBLIC = 20 unless const_defined?(:PUBLIC) - - class << self - def values - options.values - end - - def options - { - 'Private' => PRIVATE, - 'Internal' => INTERNAL, - 'Public' => PUBLIC - } - end - - def allowed_for?(user, level) - user.is_admin? || allowed_level?(level.to_i) - end - - # Return true if the specified level is allowed for the current user. - # Level should be a numeric value, e.g. `20`. - def allowed_level?(level) - valid_level?(level) && non_restricted_level?(level) - end - - def non_restricted_level?(level) - restricted_levels = current_application_settings.restricted_visibility_levels - - if restricted_levels.nil? - true - else - !restricted_levels.include?(level) - end - end - - def valid_level?(level) - options.has_value?(level) - end - end - - def private? - visibility_level_field == PRIVATE - end - - def internal? - visibility_level_field == INTERNAL - end - - def public? - visibility_level_field == PUBLIC - end - end -end diff --git a/lib/gt_one_coercion.rb b/lib/gt_one_coercion.rb deleted file mode 100644 index ef2dc09767cc09a5864ddc0b9420a492a9df9f02..0000000000000000000000000000000000000000 --- a/lib/gt_one_coercion.rb +++ /dev/null @@ -1,5 +0,0 @@ -class GtOneCoercion < Virtus::Attribute - def coerce(value) - [1, value.to_i].max - end -end diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb deleted file mode 100644 index 10efff2ae9f12f7b250c82f2cd7907a27bd7e32b..0000000000000000000000000000000000000000 --- a/lib/redcarpet/render/gitlab_html.rb +++ /dev/null @@ -1,72 +0,0 @@ -class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML - - attr_reader :template - alias_method :h, :template - - def initialize(template, color_scheme, options = {}) - @template = template - @color_scheme = color_scheme - @project = @template.instance_variable_get("@project") - @options = options.dup - super options - end - - def preprocess(full_document) - # Redcarpet doesn't allow SMB links when `safe_links_only` is enabled. - # FTP links are allowed, so we trick Redcarpet. - full_document.gsub("smb://", "ftp://smb:") - end - - # If project has issue number 39, apostrophe will be linked in - # regular text to the issue as Redcarpet will convert apostrophe to - # #39; - # We replace apostrophe with right single quote before Redcarpet - # does the processing and put the apostrophe back in postprocessing. - # This only influences regular text, code blocks are untouched. - def normal_text(text) - return text unless text.present? - text.gsub("'", "’") - end - - # Stolen from Rugments::Plugins::Redcarpet as this module is not required - # from Rugments's gem root. - def block_code(code, language) - lexer = Rugments::Lexer.find_fancy(language, code) || Rugments::Lexers::PlainText - - # XXX HACK: Redcarpet strips hard tabs out of code blocks, - # so we assume you're not using leading spaces that aren't tabs, - # and just replace them here. - if lexer.tag == 'make' - code.gsub! /^ /, "\t" - end - - formatter = Rugments::Formatters::HTML.new( - cssclass: "code highlight #{@color_scheme} #{lexer.tag}" - ) - formatter.format(lexer.lex(code)) - end - - def link(link, title, content) - h.link_to_gfm(content, link, title: title) - end - - def header(text, level) - if @options[:no_header_anchors] - "#{text}" - else - id = ActionController::Base.helpers.strip_tags(h.gfm(text)).downcase() \ - .gsub(/[^a-z0-9_-]/, '-').gsub(/-+/, '-').gsub(/^-/, '').gsub(/-$/, '') - "#{text}" - end - end - - def postprocess(full_document) - full_document.gsub!("ftp://smb:", "smb://") - - full_document.gsub!("’", "'") - unless @template.instance_variable_get("@project_wiki") || @project.nil? - full_document = h.create_relative_links(full_document) - end - h.gfm_with_options(full_document, @options) - end -end diff --git a/lib/repository_cache.rb b/lib/repository_cache.rb deleted file mode 100644 index fa016a170cd69e3ff3758c52321524bd03f7ec8a..0000000000000000000000000000000000000000 --- a/lib/repository_cache.rb +++ /dev/null @@ -1,21 +0,0 @@ -# Interface to the Redis-backed cache store used by the Repository model -class RepositoryCache - attr_reader :namespace, :backend - - def initialize(namespace, backend = Rails.cache) - @namespace = namespace - @backend = backend - end - - def cache_key(type) - "#{type}:#{namespace}" - end - - def expire(key) - backend.delete(cache_key(key)) - end - - def fetch(key, &block) - backend.fetch(cache_key(key), &block) - end -end diff --git a/lib/static_model.rb b/lib/static_model.rb deleted file mode 100644 index 185921d8fbee0ccd070d458a11d01e7e3215d8ff..0000000000000000000000000000000000000000 --- a/lib/static_model.rb +++ /dev/null @@ -1,47 +0,0 @@ -# Provides an ActiveRecord-like interface to a model whose data is not persisted to a database. -module StaticModel - extend ActiveSupport::Concern - - module ClassMethods - # Used by ActiveRecord's polymorphic association to set object_id - def primary_key - 'id' - end - - # Used by ActiveRecord's polymorphic association to set object_type - def base_class - self - end - end - - # Used by AR for fetching attributes - # - # Pass it along if we respond to it. - def [](key) - send(key) if respond_to?(key) - end - - def to_param - id - end - - def new_record? - false - end - - def persisted? - false - end - - def destroyed? - false - end - - def ==(other) - if other.is_a? ::StaticModel - id == other.id - else - super - end - end -end diff --git a/lib/support/deploy/deploy.sh b/lib/support/deploy/deploy.sh deleted file mode 100755 index adea4c7a747db27ca2b3f03cff55ece93e0506dc..0000000000000000000000000000000000000000 --- a/lib/support/deploy/deploy.sh +++ /dev/null @@ -1,45 +0,0 @@ -# This is deploy script we use to update staging server -# You can always modify it for your needs :) - -# If any command return non-zero status - stop deploy -set -e - -echo 'Deploy: Stopping sidekiq..' -cd /home/git/gitlab/ && sudo -u git -H bundle exec rake sidekiq:stop RAILS_ENV=production - -echo 'Deploy: Show deploy index page' -sudo -u git -H cp /home/git/gitlab/public/deploy.html /home/git/gitlab/public/index.html - -echo 'Deploy: Starting backup...' -cd /home/git/gitlab/ && sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production - -echo 'Deploy: Stop GitLab server' -sudo service gitlab stop - -echo 'Deploy: Get latest code' -cd /home/git/gitlab/ - -# clean working directory -sudo -u git -H git stash - -# change branch to -sudo -u git -H git pull origin master - -echo 'Deploy: Bundle and migrate' - -# change it to your needs -sudo -u git -H bundle --without aws development test mysql --deployment - -sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production -sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production -sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production -sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production - -# return stashed changes (if necessary) -# sudo -u git -H git stash pop - -echo 'Deploy: Starting GitLab server...' -sudo service gitlab start - -sudo -u git -H rm /home/git/gitlab/public/index.html -echo 'Deploy: Done' diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab deleted file mode 100755 index b066a1a69350764d36158879f6afd589a53c71f3..0000000000000000000000000000000000000000 --- a/lib/support/init.d/gitlab +++ /dev/null @@ -1,301 +0,0 @@ -#! /bin/sh - -# GITLAB -# Maintainer: @randx -# Authors: rovanion.luckey@gmail.com, @randx - -### BEGIN INIT INFO -# Provides: gitlab -# Required-Start: $local_fs $remote_fs $network $syslog redis-server -# Required-Stop: $local_fs $remote_fs $network $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: GitLab git repository management -# Description: GitLab git repository management -# chkconfig: - 85 14 -### END INIT INFO - - -### -# DO NOT EDIT THIS FILE! -# This file will be overwritten on update. -# Instead add/change your variables in /etc/default/gitlab -# An example defaults file can be found in lib/support/init.d/gitlab.default.example -### - - -### Environment variables -RAILS_ENV="production" - -# Script variable names should be lower-case not to conflict with -# internal /bin/sh variables such as PATH, EDITOR or SHELL. -app_user="git" -app_root="/home/$app_user/gitlab" -pid_path="$app_root/tmp/pids" -socket_path="$app_root/tmp/sockets" -web_server_pid_path="$pid_path/unicorn.pid" -sidekiq_pid_path="$pid_path/sidekiq.pid" - -# Read configuration variable file if it is present -test -f /etc/default/gitlab && . /etc/default/gitlab - -# Switch to the app_user if it is not he/she who is running the script. -if [ "$USER" != "$app_user" ]; then - eval su - "$app_user" -c $(echo \")$0 "$@"$(echo \"); exit; -fi - -# Switch to the gitlab path, exit on failure. -if ! cd "$app_root" ; then - echo "Failed to cd into $app_root, exiting!"; exit 1 -fi - - -### Init Script functions - -## Gets the pids from the files -check_pids(){ - if ! mkdir -p "$pid_path"; then - echo "Could not create the path $pid_path needed to store the pids." - exit 1 - fi - # If there exists a file which should hold the value of the Unicorn pid: read it. - if [ -f "$web_server_pid_path" ]; then - wpid=$(cat "$web_server_pid_path") - else - wpid=0 - fi - if [ -f "$sidekiq_pid_path" ]; then - spid=$(cat "$sidekiq_pid_path") - else - spid=0 - fi -} - -## Called when we have started the two processes and are waiting for their pid files. -wait_for_pids(){ - # We are sleeping a bit here mostly because sidekiq is slow at writing it's pid - i=0; - while [ ! -f $web_server_pid_path -o ! -f $sidekiq_pid_path ]; do - sleep 0.1; - i=$((i+1)) - if [ $((i%10)) = 0 ]; then - echo -n "." - elif [ $((i)) = 301 ]; then - echo "Waited 30s for the processes to write their pids, something probably went wrong." - exit 1; - fi - done - echo -} - -# We use the pids in so many parts of the script it makes sense to always check them. -# Only after start() is run should the pids change. Sidekiq sets it's own pid. -check_pids - - -## Checks whether the different parts of the service are already running or not. -check_status(){ - check_pids - # If the web server is running kill -0 $wpid returns true, or rather 0. - # Checks of *_status should only check for == 0 or != 0, never anything else. - if [ $wpid -ne 0 ]; then - kill -0 "$wpid" 2>/dev/null - web_status="$?" - else - web_status="-1" - fi - if [ $spid -ne 0 ]; then - kill -0 "$spid" 2>/dev/null - sidekiq_status="$?" - else - sidekiq_status="-1" - fi - if [ $web_status = 0 -a $sidekiq_status = 0 ]; then - gitlab_status=0 - else - # http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html - # code 3 means 'program is not running' - gitlab_status=3 - fi -} - -## Check for stale pids and remove them if necessary. -check_stale_pids(){ - check_status - # If there is a pid it is something else than 0, the service is running if - # *_status is == 0. - if [ "$wpid" != "0" -a "$web_status" != "0" ]; then - echo "Removing stale Unicorn web server pid. This is most likely caused by the web server crashing the last time it ran." - if ! rm "$web_server_pid_path"; then - echo "Unable to remove stale pid, exiting." - exit 1 - fi - fi - if [ "$spid" != "0" -a "$sidekiq_status" != "0" ]; then - echo "Removing stale Sidekiq job dispatcher pid. This is most likely caused by Sidekiq crashing the last time it ran." - if ! rm "$sidekiq_pid_path"; then - echo "Unable to remove stale pid, exiting" - exit 1 - fi - fi -} - -## If no parts of the service is running, bail out. -exit_if_not_running(){ - check_stale_pids - if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then - echo "GitLab is not running." - exit - fi -} - -## Starts Unicorn and Sidekiq if they're not running. -start_gitlab() { - check_stale_pids - - if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then - echo -n "Starting both the GitLab Unicorn and Sidekiq" - elif [ "$web_status" != "0" ]; then - echo -n "Starting GitLab Unicorn" - elif [ "$sidekiq_status" != "0" ]; then - echo -n "Starting GitLab Sidekiq" - fi - - # Then check if the service is running. If it is: don't start again. - if [ "$web_status" = "0" ]; then - echo "The Unicorn web server already running with pid $wpid, not restarting." - else - # Remove old socket if it exists - rm -f "$socket_path"/gitlab.socket 2>/dev/null - # Start the web server - RAILS_ENV=$RAILS_ENV bin/web start - fi - - # If sidekiq is already running, don't start it again. - if [ "$sidekiq_status" = "0" ]; then - echo "The Sidekiq job dispatcher is already running with pid $spid, not restarting" - else - RAILS_ENV=$RAILS_ENV bin/background_jobs start & - fi - - # Wait for the pids to be planted - wait_for_pids - # Finally check the status to tell wether or not GitLab is running - print_status -} - -## Asks the Unicorn and the Sidekiq if they would be so kind as to stop, if not kills them. -stop_gitlab() { - exit_if_not_running - - if [ "$web_status" = "0" -a "$sidekiq_status" = "0" ]; then - echo -n "Shutting down both Unicorn and Sidekiq" - elif [ "$web_status" = "0" ]; then - echo -n "Shutting down Unicorn" - elif [ "$sidekiq_status" = "0" ]; then - echo -n "Shutting down Sidekiq" - fi - - # If the Unicorn web server is running, tell it to stop; - if [ "$web_status" = "0" ]; then - RAILS_ENV=$RAILS_ENV bin/web stop - fi - # And do the same thing for the Sidekiq. - if [ "$sidekiq_status" = "0" ]; then - RAILS_ENV=$RAILS_ENV bin/background_jobs stop - fi - - # If something needs to be stopped, lets wait for it to stop. Never use SIGKILL in a script. - while [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; do - sleep 1 - check_status - printf "." - if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then - printf "\n" - break - fi - done - - sleep 1 - # Cleaning up unused pids - rm "$web_server_pid_path" 2>/dev/null - # rm "$sidekiq_pid_path" # Sidekiq seems to be cleaning up it's own pid. - - print_status -} - -## Prints the status of GitLab and it's components. -print_status() { - check_status - if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then - echo "GitLab is not running." - return - fi - if [ "$web_status" = "0" ]; then - echo "The GitLab Unicorn web server with pid $wpid is running." - else - printf "The GitLab Unicorn web server is \033[31mnot running\033[0m.\n" - fi - if [ "$sidekiq_status" = "0" ]; then - echo "The GitLab Sidekiq job dispatcher with pid $spid is running." - else - printf "The GitLab Sidekiq job dispatcher is \033[31mnot running\033[0m.\n" - fi - if [ "$web_status" = "0" -a "$sidekiq_status" = "0" ]; then - printf "GitLab and all its components are \033[32mup and running\033[0m.\n" - fi -} - -## Tells unicorn to reload it's config and Sidekiq to restart -reload_gitlab(){ - exit_if_not_running - if [ "$wpid" = "0" ];then - echo "The GitLab Unicorn Web server is not running thus its configuration can't be reloaded." - exit 1 - fi - printf "Reloading GitLab Unicorn configuration... " - RAILS_ENV=$RAILS_ENV bin/web reload - echo "Done." - echo "Restarting GitLab Sidekiq since it isn't capable of reloading its config..." - RAILS_ENV=$RAILS_ENV bin/background_jobs restart - - wait_for_pids - print_status -} - -## Restarts Sidekiq and Unicorn. -restart_gitlab(){ - check_status - if [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; then - stop_gitlab - fi - start_gitlab -} - - -### Finally the input handling. - -case "$1" in - start) - start_gitlab - ;; - stop) - stop_gitlab - ;; - restart) - restart_gitlab - ;; - reload|force-reload) - reload_gitlab - ;; - status) - print_status - exit $gitlab_status - ;; - *) - echo "Usage: service gitlab {start|stop|restart|reload|status}" - exit 1 - ;; -esac - -exit diff --git a/lib/support/init.d/gitlab.default.example b/lib/support/init.d/gitlab.default.example deleted file mode 100755 index 9951bacedf513b368ece97d11f08546d93485810..0000000000000000000000000000000000000000 --- a/lib/support/init.d/gitlab.default.example +++ /dev/null @@ -1,31 +0,0 @@ -# Copy this lib/support/init.d/gitlab.default.example file to -# /etc/default/gitlab in order for it to apply to your system. - -# RAILS_ENV defines the type of installation that is running. -# Normal values are "production", "test" and "development". -RAILS_ENV="production" - -# app_user defines the user that GitLab is run as. -# The default is "git". -app_user="git" - -# app_root defines the folder in which gitlab and it's components are installed. -# The default is "/home/$app_user/gitlab" -app_root="/home/$app_user/gitlab" - -# pid_path defines a folder in which the gitlab and it's components place their pids. -# This variable is also used below to define the relevant pids for the gitlab components. -# The default is "$app_root/tmp/pids" -pid_path="$app_root/tmp/pids" - -# socket_path defines the folder in which gitlab places the sockets -#The default is "$app_root/tmp/sockets" -socket_path="$app_root/tmp/sockets" - -# web_server_pid_path defines the path in which to create the pid file fo the web_server -# The default is "$pid_path/unicorn.pid" -web_server_pid_path="$pid_path/unicorn.pid" - -# sidekiq_pid_path defines the path in which to create the pid file for sidekiq -# The default is "$pid_path/sidekiq.pid" -sidekiq_pid_path="$pid_path/sidekiq.pid" diff --git a/lib/support/logrotate/gitlab b/lib/support/logrotate/gitlab deleted file mode 100644 index d9b07b61ec34379a6b927e033dec93d85eb68719..0000000000000000000000000000000000000000 --- a/lib/support/logrotate/gitlab +++ /dev/null @@ -1,20 +0,0 @@ -# GitLab logrotate settings -# based on: http://stackoverflow.com/a/4883967 - -/home/git/gitlab/log/*.log { - daily - missingok - rotate 90 - compress - notifempty - copytruncate -} - -/home/git/gitlab-shell/gitlab-shell.log { - daily - missingok - rotate 90 - compress - notifempty - copytruncate -} diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab deleted file mode 100644 index 62a4276536c4d733bdcbff28720a41111e657a26..0000000000000000000000000000000000000000 --- a/lib/support/nginx/gitlab +++ /dev/null @@ -1,115 +0,0 @@ -## GitLab -## Contributors: randx, yin8086, sashkab, orkoden, axilleas, bbodenmiller, DouweM -## -## Lines starting with two hashes (##) are comments with information. -## Lines starting with one hash (#) are configuration parameters that can be uncommented. -## -################################## -## CHUNKED TRANSFER ## -################################## -## -## It is a known issue that Git-over-HTTP requires chunked transfer encoding [0] -## which is not supported by Nginx < 1.3.9 [1]. As a result, pushing a large object -## with Git (i.e. a single large file) can lead to a 411 error. In theory you can get -## around this by tweaking this configuration file and either: -## - installing an old version of Nginx with the chunkin module [2] compiled in, or -## - using a newer version of Nginx. -## -## At the time of writing we do not know if either of these theoretical solutions works. -## As a workaround users can use Git over SSH to push large files. -## -## [0] https://git.kernel.org/cgit/git/git.git/tree/Documentation/technical/http-protocol.txt#n99 -## [1] https://github.com/agentzh/chunkin-nginx-module#status -## [2] https://github.com/agentzh/chunkin-nginx-module -## -################################### -## configuration ## -################################### -## -## See installation.md#using-https for additional HTTPS configuration details. - -upstream gitlab { - server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0; -} - -## Normal HTTP host -server { - listen 0.0.0.0:80 default_server; - listen [::]:80 default_server; - server_name YOUR_SERVER_FQDN; ## Replace this with something like gitlab.example.com - server_tokens off; ## Don't show the nginx version number, a security best practice - root /home/git/gitlab/public; - - ## Increase this if you want to upload large attachments - ## Or if you want to accept large git objects over http - client_max_body_size 20m; - - ## See app/controllers/application_controller.rb for headers set - - ## Individual nginx logs for this GitLab vhost - access_log /var/log/nginx/gitlab_access.log; - error_log /var/log/nginx/gitlab_error.log; - - location / { - ## Serve static files from defined root folder. - ## @gitlab is a named location for the upstream fallback, see below. - try_files $uri $uri/index.html $uri.html @gitlab; - } - - ## We route uploads through GitLab to prevent XSS and enforce access control. - location /uploads/ { - ## If you use HTTPS make sure you disable gzip compression - ## to be safe against BREACH attack. - # gzip off; - - ## https://github.com/gitlabhq/gitlabhq/issues/694 - ## Some requests take more than 30 seconds. - proxy_read_timeout 300; - proxy_connect_timeout 300; - proxy_redirect off; - - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Frame-Options SAMEORIGIN; - - proxy_pass http://gitlab; - } - - ## If a file, which is not found in the root folder is requested, - ## then the proxy passes the request to the upsteam (gitlab unicorn). - location @gitlab { - ## If you use HTTPS make sure you disable gzip compression - ## to be safe against BREACH attack. - # gzip off; - - ## https://github.com/gitlabhq/gitlabhq/issues/694 - ## Some requests take more than 30 seconds. - proxy_read_timeout 300; - proxy_connect_timeout 300; - proxy_redirect off; - - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Frame-Options SAMEORIGIN; - - proxy_pass http://gitlab; - } - - ## Enable gzip compression as per rails guide: - ## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression - ## WARNING: If you are using relative urls remove the block below - ## See config/application.rb under "Relative url support" for the list of - ## other files that need to be changed for relative url support - location ~ ^/(assets)/ { - root /home/git/gitlab/public; - gzip_static on; # to serve pre-gzipped version - expires max; - add_header Cache-Control public; - } - - error_page 502 /502.html; -} diff --git a/lib/support/nginx/gitlab-ssl b/lib/support/nginx/gitlab-ssl deleted file mode 100644 index 2aefc94469824694fa29e2af0a442072667c9a8e..0000000000000000000000000000000000000000 --- a/lib/support/nginx/gitlab-ssl +++ /dev/null @@ -1,162 +0,0 @@ -## GitLab -## Contributors: randx, yin8086, sashkab, orkoden, axilleas, bbodenmiller, DouweM -## -## Modified from nginx http version -## Modified from http://blog.phusion.nl/2012/04/21/tutorial-setting-up-gitlab-on-debian-6/ -## Modified from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html -## -## Lines starting with two hashes (##) are comments with information. -## Lines starting with one hash (#) are configuration parameters that can be uncommented. -## -################################## -## CHUNKED TRANSFER ## -################################## -## -## It is a known issue that Git-over-HTTP requires chunked transfer encoding [0] -## which is not supported by Nginx < 1.3.9 [1]. As a result, pushing a large object -## with Git (i.e. a single large file) can lead to a 411 error. In theory you can get -## around this by tweaking this configuration file and either: -## - installing an old version of Nginx with the chunkin module [2] compiled in, or -## - using a newer version of Nginx. -## -## At the time of writing we do not know if either of these theoretical solutions works. -## As a workaround users can use Git over SSH to push large files. -## -## [0] https://git.kernel.org/cgit/git/git.git/tree/Documentation/technical/http-protocol.txt#n99 -## [1] https://github.com/agentzh/chunkin-nginx-module#status -## [2] https://github.com/agentzh/chunkin-nginx-module -## -################################### -## configuration ## -################################### -## -## See installation.md#using-https for additional HTTPS configuration details. - -upstream gitlab { - server unix:/home/git/gitlab/tmp/sockets/gitlab.socket fail_timeout=0; -} - -## Redirects all HTTP traffic to the HTTPS host -server { - listen 0.0.0.0:80; - listen [::]:80 ipv6only=on default_server; - server_name YOUR_SERVER_FQDN; ## Replace this with something like gitlab.example.com - server_tokens off; ## Don't show the nginx version number, a security best practice - return 301 https://$server_name$request_uri; - access_log /var/log/nginx/gitlab_access.log; - error_log /var/log/nginx/gitlab_error.log; -} - - -## HTTPS host -server { - listen 0.0.0.0:443 ssl; - listen [::]:443 ipv6only=on ssl default_server; - server_name YOUR_SERVER_FQDN; ## Replace this with something like gitlab.example.com - server_tokens off; ## Don't show the nginx version number, a security best practice - root /home/git/gitlab/public; - - ## Increase this if you want to upload large attachments - ## Or if you want to accept large git objects over http - client_max_body_size 20m; - - ## Strong SSL Security - ## https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html & https://cipherli.st/ - ssl on; - ssl_certificate /etc/nginx/ssl/gitlab.crt; - ssl_certificate_key /etc/nginx/ssl/gitlab.key; - - # GitLab needs backwards compatible ciphers to retain compatibility with Java IDEs - ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4"; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; - ssl_session_cache shared:SSL:10m; - ssl_session_timeout 5m; - - ## See app/controllers/application_controller.rb for headers set - - ## [Optional] If your certficate has OCSP, enable OCSP stapling to reduce the overhead and latency of running SSL. - ## Replace with your ssl_trusted_certificate. For more info see: - ## - https://medium.com/devops-programming/4445f4862461 - ## - https://www.ruby-forum.com/topic/4419319 - ## - https://www.digitalocean.com/community/tutorials/how-to-configure-ocsp-stapling-on-apache-and-nginx - # ssl_stapling on; - # ssl_stapling_verify on; - # ssl_trusted_certificate /etc/nginx/ssl/stapling.trusted.crt; - # resolver 208.67.222.222 208.67.222.220 valid=300s; # Can change to your DNS resolver if desired - # resolver_timeout 5s; - - ## [Optional] Generate a stronger DHE parameter: - ## sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 - ## - # ssl_dhparam /etc/ssl/certs/dhparam.pem; - - ## Individual nginx logs for this GitLab vhost - access_log /var/log/nginx/gitlab_access.log; - error_log /var/log/nginx/gitlab_error.log; - - location / { - ## Serve static files from defined root folder. - ## @gitlab is a named location for the upstream fallback, see below. - try_files $uri $uri/index.html $uri.html @gitlab; - } - - ## We route uploads through GitLab to prevent XSS and enforce access control. - location /uploads/ { - ## If you use HTTPS make sure you disable gzip compression - ## to be safe against BREACH attack. - gzip off; - - ## https://github.com/gitlabhq/gitlabhq/issues/694 - ## Some requests take more than 30 seconds. - proxy_read_timeout 300; - proxy_connect_timeout 300; - proxy_redirect off; - - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-Ssl on; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Frame-Options SAMEORIGIN; - - proxy_pass http://gitlab; - } - - ## If a file, which is not found in the root folder is requested, - ## then the proxy passes the request to the upsteam (gitlab unicorn). - location @gitlab { - ## If you use HTTPS make sure you disable gzip compression - ## to be safe against BREACH attack. - gzip off; - - ## https://github.com/gitlabhq/gitlabhq/issues/694 - ## Some requests take more than 30 seconds. - proxy_read_timeout 300; - proxy_connect_timeout 300; - proxy_redirect off; - - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-Ssl on; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Frame-Options SAMEORIGIN; - - proxy_pass http://gitlab; - } - - ## Enable gzip compression as per rails guide: - ## http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression - ## WARNING: If you are using relative urls remove the block below - ## See config/application.rb under "Relative url support" for the list of - ## other files that need to be changed for relative url support - location ~ ^/(assets)/ { - root /home/git/gitlab/public; - gzip_static on; # to serve pre-gzipped version - expires max; - add_header Cache-Control public; - } - - error_page 502 /502.html; -} diff --git a/lib/tasks/.gitkeep b/lib/tasks/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/lib/tasks/brakeman.rake b/lib/tasks/brakeman.rake deleted file mode 100644 index 3a225801ff21d884aa97ac5f1383d59e734de7ba..0000000000000000000000000000000000000000 --- a/lib/tasks/brakeman.rake +++ /dev/null @@ -1,9 +0,0 @@ -desc 'Security check via brakeman' -task :brakeman do - if system("brakeman --skip-files lib/backup/repository.rb -w3 -z") - puts 'Security check succeed' - else - puts 'Security check failed' - exit 1 - end -end diff --git a/lib/tasks/cache.rake b/lib/tasks/cache.rake deleted file mode 100644 index 753a5a11070b9f9565b5d552c96d2119437df4b0..0000000000000000000000000000000000000000 --- a/lib/tasks/cache.rake +++ /dev/null @@ -1,11 +0,0 @@ -namespace :cache do - desc "GITLAB | Clear redis cache" - task :clear => :environment do - # Hack into Rails.cache until https://github.com/redis-store/redis-store/pull/225 - # is accepted (I hope) and we can update the redis-store gem. - redis_store = Rails.cache.instance_variable_get(:@data) - redis_store.keys.each_slice(1000) do |key_slice| - redis_store.del(*key_slice) - end - end -end diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake deleted file mode 100644 index 058c74170404d90e9dc6b748b3def290b4eee66f..0000000000000000000000000000000000000000 --- a/lib/tasks/dev.rake +++ /dev/null @@ -1,10 +0,0 @@ -task dev: ["dev:setup"] - -namespace :dev do - desc "GITLAB | Setup developer environment (db, fixtures)" - task :setup => :environment do - ENV['force'] = 'yes' - Rake::Task["gitlab:setup"].invoke - Rake::Task["gitlab:shell:setup"].invoke - end -end diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake deleted file mode 100644 index 84445b3bf2fc7ee529f20c24ac70a6abccf471f8..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/backup.rake +++ /dev/null @@ -1,106 +0,0 @@ -require 'active_record/fixtures' - -namespace :gitlab do - namespace :backup do - # Create backup of GitLab system - desc "GITLAB | Create a backup of the GitLab system" - task create: :environment do - warn_user_is_not_gitlab - configure_cron_mode - - Rake::Task["gitlab:backup:db:create"].invoke - Rake::Task["gitlab:backup:repo:create"].invoke - Rake::Task["gitlab:backup:uploads:create"].invoke - - backup = Backup::Manager.new - backup.pack - backup.cleanup - backup.remove_old - end - - # Restore backup of GitLab system - desc "GITLAB | Restore a previously created backup" - task restore: :environment do - warn_user_is_not_gitlab - configure_cron_mode - - backup = Backup::Manager.new - backup.unpack - - Rake::Task["gitlab:backup:db:restore"].invoke unless backup.skipped?("db") - Rake::Task["gitlab:backup:repo:restore"].invoke unless backup.skipped?("repositories") - Rake::Task["gitlab:backup:uploads:restore"].invoke unless backup.skipped?("uploads") - Rake::Task["gitlab:shell:setup"].invoke - - backup.cleanup - end - - namespace :repo do - task create: :environment do - $progress.puts "Dumping repositories ...".blue - - if ENV["SKIP"] && ENV["SKIP"].include?("repositories") - $progress.puts "[SKIPPED]".cyan - else - Backup::Repository.new.dump - $progress.puts "done".green - end - end - - task restore: :environment do - $progress.puts "Restoring repositories ...".blue - Backup::Repository.new.restore - $progress.puts "done".green - end - end - - namespace :db do - task create: :environment do - $progress.puts "Dumping database ... ".blue - - if ENV["SKIP"] && ENV["SKIP"].include?("db") - $progress.puts "[SKIPPED]".cyan - else - Backup::Database.new.dump - $progress.puts "done".green - end - end - - task restore: :environment do - $progress.puts "Restoring database ... ".blue - Backup::Database.new.restore - $progress.puts "done".green - end - end - - namespace :uploads do - task create: :environment do - $progress.puts "Dumping uploads ... ".blue - - if ENV["SKIP"] && ENV["SKIP"].include?("uploads") - $progress.puts "[SKIPPED]".cyan - else - Backup::Uploads.new.dump - $progress.puts "done".green - end - end - - task restore: :environment do - $progress.puts "Restoring uploads ... ".blue - Backup::Uploads.new.restore - $progress.puts "done".green - end - end - - def configure_cron_mode - if ENV['CRON'] - # We need an object we can say 'puts' and 'print' to; let's use a - # StringIO. - require 'stringio' - $progress = StringIO.new - else - $progress = $stdout - end - end - end # namespace end: backup -end # namespace end: gitlab diff --git a/lib/tasks/gitlab/bulk_add_permission.rake b/lib/tasks/gitlab/bulk_add_permission.rake deleted file mode 100644 index 3d8c171dfa3f1368cd38f0880cb1390d403a6896..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/bulk_add_permission.rake +++ /dev/null @@ -1,48 +0,0 @@ -namespace :gitlab do - namespace :import do - desc "GITLAB | Add all users to all projects (admin users are added as masters)" - task all_users_to_all_projects: :environment do |t, args| - user_ids = User.where(admin: false).pluck(:id) - admin_ids = User.where(admin: true).pluck(:id) - projects_ids = Project.pluck(:id) - - puts "Importing #{user_ids.size} users into #{projects_ids.size} projects" - ProjectMember.add_users_into_projects(projects_ids, user_ids, ProjectMember::DEVELOPER) - - puts "Importing #{admin_ids.size} admins into #{projects_ids.size} projects" - ProjectMember.add_users_into_projects(projects_ids, admin_ids, ProjectMember::MASTER) - end - - desc "GITLAB | Add a specific user to all projects (as a developer)" - task :user_to_projects, [:email] => :environment do |t, args| - user = User.find_by(email: args.email) - project_ids = Project.pluck(:id) - puts "Importing #{user.email} users into #{project_ids.size} projects" - ProjectMember.add_users_into_projects(project_ids, Array.wrap(user.id), ProjectMember::DEVELOPER) - end - - desc "GITLAB | Add all users to all groups (admin users are added as owners)" - task all_users_to_all_groups: :environment do |t, args| - user_ids = User.where(admin: false).pluck(:id) - admin_ids = User.where(admin: true).pluck(:id) - groups = Group.all - - puts "Importing #{user_ids.size} users into #{groups.size} groups" - puts "Importing #{admin_ids.size} admins into #{groups.size} groups" - groups.each do |group| - group.add_users(user_ids, GroupMember::DEVELOPER) - group.add_users(admin_ids, GroupMember::OWNER) - end - end - - desc "GITLAB | Add a specific user to all groups (as a developer)" - task :user_to_groups, [:email] => :environment do |t, args| - user = User.find_by_email args.email - groups = Group.all - puts "Importing #{user.email} users into #{groups.size} groups" - groups.each do |group| - group.add_users(Array.wrap(user.id), GroupMember::DEVELOPER) - end - end - end -end diff --git a/lib/tasks/gitlab/cleanup.rake b/lib/tasks/gitlab/cleanup.rake deleted file mode 100644 index 3c9802a0be4366c80552c8e41f728bb068169fc2..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/cleanup.rake +++ /dev/null @@ -1,113 +0,0 @@ -namespace :gitlab do - namespace :cleanup do - desc "GITLAB | Cleanup | Clean namespaces" - task dirs: :environment do - warn_user_is_not_gitlab - remove_flag = ENV['REMOVE'] - - - namespaces = Namespace.pluck(:path) - git_base_path = Gitlab.config.gitlab_shell.repos_path - all_dirs = Dir.glob(git_base_path + '/*') - - puts git_base_path.yellow - puts "Looking for directories to remove... " - - all_dirs.reject! do |dir| - # skip if git repo - dir =~ /.git$/ - end - - all_dirs.reject! do |dir| - dir_name = File.basename dir - - # skip if namespace present - namespaces.include?(dir_name) - end - - all_dirs.each do |dir_path| - - if remove_flag - if FileUtils.rm_rf dir_path - puts "Removed...#{dir_path}".red - else - puts "Cannot remove #{dir_path}".red - end - else - puts "Can be removed: #{dir_path}".red - end - end - - unless remove_flag - puts "To cleanup this directories run this command with REMOVE=true".yellow - end - end - - desc "GITLAB | Cleanup | Clean repositories" - task repos: :environment do - warn_user_is_not_gitlab - remove_flag = ENV['REMOVE'] - - git_base_path = Gitlab.config.gitlab_shell.repos_path - all_dirs = Dir.glob(git_base_path + '/*') - - global_projects = Project.where(namespace_id: nil).pluck(:path) - - puts git_base_path.yellow - puts "Looking for global repos to remove... " - - # skip non git repo - all_dirs.select! do |dir| - dir =~ /.git$/ - end - - # skip existing repos - all_dirs.reject! do |dir| - repo_name = File.basename dir - path = repo_name.gsub(/\.git$/, "") - global_projects.include?(path) - end - - all_dirs.each do |dir_path| - if remove_flag - if FileUtils.rm_rf dir_path - puts "Removed...#{dir_path}".red - else - puts "Cannot remove #{dir_path}".red - end - else - puts "Can be removed: #{dir_path}".red - end - end - - unless remove_flag - puts "To cleanup this directories run this command with REMOVE=true".yellow - end - end - - desc "GITLAB | Cleanup | Block users that have been removed in LDAP" - task block_removed_ldap_users: :environment do - warn_user_is_not_gitlab - block_flag = ENV['BLOCK'] - - User.find_each do |user| - next unless user.ldap_user? - print "#{user.name} (#{user.ldap_identity.extern_uid}) ..." - if Gitlab::LDAP::Access.allowed?(user) - puts " [OK]".green - else - if block_flag - user.block! unless user.blocked? - puts " [BLOCKED]".red - else - puts " [NOT IN LDAP]".yellow - end - end - end - - unless block_flag - puts "To block these users run this command with BLOCK=true".yellow - end - end - end -end diff --git a/lib/tasks/gitlab/db/drop_all_postgres_sequences.rake b/lib/tasks/gitlab/db/drop_all_postgres_sequences.rake deleted file mode 100644 index e9cf0a9b5e862cc16d1b886ecac14ff424d8807c..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/db/drop_all_postgres_sequences.rake +++ /dev/null @@ -1,10 +0,0 @@ -namespace :gitlab do - namespace :db do - task drop_all_postgres_sequences: :environment do - connection = ActiveRecord::Base.connection - connection.execute("SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';").each do |sequence| - connection.execute("DROP SEQUENCE #{sequence['relname']}") - end - end - end -end diff --git a/lib/tasks/gitlab/db/drop_all_tables.rake b/lib/tasks/gitlab/db/drop_all_tables.rake deleted file mode 100644 index a66030ab93a9e96f3cc1ac6cb3fc7447d36b4a8f..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/db/drop_all_tables.rake +++ /dev/null @@ -1,10 +0,0 @@ -namespace :gitlab do - namespace :db do - task drop_all_tables: :environment do - connection = ActiveRecord::Base.connection - connection.tables.each do |table| - connection.drop_table(table) - end - end - end -end diff --git a/lib/tasks/gitlab/enable_automerge.rake b/lib/tasks/gitlab/enable_automerge.rake deleted file mode 100644 index aa9869daf2f9e3afef4f19179e3c9e8cb6512ad3..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/enable_automerge.rake +++ /dev/null @@ -1,39 +0,0 @@ -namespace :gitlab do - namespace :satellites do - desc "GITLAB | Create satellite repos" - task create: :environment do - create_satellites - end - end - - def create_satellites - warn_user_is_not_gitlab - - print "Creating satellites for ..." - unless Project.count > 0 - puts "skipping, because you have no projects".magenta - return - end - puts "" - - Project.find_each(batch_size: 100) do |project| - print "#{project.name_with_namespace.yellow} ... " - - unless project.repo_exists? - puts "skipping, because the repo is empty".magenta - next - end - - if project.satellite.exists? - puts "exists already".green - else - print "\n... " - if project.satellite.create - puts "created".green - else - puts "error".red - end - end - end - end -end diff --git a/lib/tasks/gitlab/generate_docs.rake b/lib/tasks/gitlab/generate_docs.rake deleted file mode 100644 index 332cd61f84c29f0fba46b6f0151534ec842bb366..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/generate_docs.rake +++ /dev/null @@ -1,7 +0,0 @@ -namespace :gitlab do - desc "GITLAB | Generate sdocs for project" - task generate_docs: :environment do - system(*%W(bundle exec sdoc -o doc/code app lib)) - end -end - diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake deleted file mode 100644 index 20abb2fa5001c01e72c58817318228ebc3733994..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/import.rake +++ /dev/null @@ -1,77 +0,0 @@ -namespace :gitlab do - namespace :import do - # How to use: - # - # 1. copy the bare repos under the repos_path (commonly /home/git/repositories) - # 2. run: bundle exec rake gitlab:import:repos RAILS_ENV=production - # - # Notes: - # * The project owner will set to the first administator of the system - # * Existing projects will be skipped - # - desc "GITLAB | Import bare repositories from gitlab_shell -> repos_path into GitLab project instance" - task repos: :environment do - - git_base_path = Gitlab.config.gitlab_shell.repos_path - repos_to_import = Dir.glob(git_base_path + '/**/*.git') - - repos_to_import.each do |repo_path| - # strip repo base path - repo_path[0..git_base_path.length] = '' - - path = repo_path.sub(/\.git$/, '') - group_name, name = File.split(path) - group_name = nil if group_name == '.' - - puts "Processing #{repo_path}".yellow - - if path.end_with?('.wiki') - puts " * Skipping wiki repo" - next - end - - project = Project.find_with_namespace(path) - - if project - puts " * #{project.name} (#{repo_path}) exists" - else - user = User.admins.first - - project_params = { - name: name, - path: name - } - - # find group namespace - if group_name - group = Namespace.find_by(path: group_name) - # create group namespace - unless group - group = Group.new(:name => group_name) - group.path = group_name - group.owner = user - if group.save - puts " * Created Group #{group.name} (#{group.id})".green - else - puts " * Failed trying to create group #{group.name}".red - end - end - # set project group - project_params[:namespace_id] = group.id - end - - project = Projects::CreateService.new(user, project_params).execute - - if project.valid? - puts " * Created #{project.name} (#{repo_path})".green - else - puts " * Failed trying to create #{project.name} (#{repo_path})".red - puts " Validation Errors: #{project.errors.messages}".red - end - end - end - - puts "Done!".green - end - end -end diff --git a/lib/tasks/gitlab/info.rake b/lib/tasks/gitlab/info.rake deleted file mode 100644 index 72452e1d8eab2b30e6629eb80c464a67af24a987..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/info.rake +++ /dev/null @@ -1,72 +0,0 @@ -namespace :gitlab do - namespace :env do - desc "GITLAB | Show information about GitLab and its environment" - task info: :environment do - - # check if there is an RVM environment - rvm_version = run_and_match(%W(rvm --version), /[\d\.]+/).try(:to_s) - # check Ruby version - ruby_version = run_and_match(%W(ruby --version), /[\d\.p]+/).try(:to_s) - # check Gem version - gem_version = run(%W(gem --version)) - # check Bundler version - bunder_version = run_and_match(%W(bundle --version), /[\d\.]+/).try(:to_s) - # check Bundler version - rake_version = run_and_match(%W(rake --version), /[\d\.]+/).try(:to_s) - - puts "" - puts "System information".yellow - puts "System:\t\t#{os_name || "unknown".red}" - puts "Current User:\t#{run(%W(whoami))}" - puts "Using RVM:\t#{rvm_version.present? ? "yes".green : "no"}" - puts "RVM Version:\t#{rvm_version}" if rvm_version.present? - puts "Ruby Version:\t#{ruby_version || "unknown".red}" - puts "Gem Version:\t#{gem_version || "unknown".red}" - puts "Bundler Version:#{bunder_version || "unknown".red}" - puts "Rake Version:\t#{rake_version || "unknown".red}" - puts "Sidekiq Version:#{Sidekiq::VERSION}" - - - # check database adapter - database_adapter = ActiveRecord::Base.connection.adapter_name.downcase - - project = Project.new(path: "some-project") - project.path = "some-project" - # construct clone URLs - http_clone_url = project.http_url_to_repo - ssh_clone_url = project.ssh_url_to_repo - - omniauth_providers = Gitlab.config.omniauth.providers - omniauth_providers.map! { |provider| provider['name'] } - - puts "" - puts "GitLab information".yellow - puts "Version:\t#{Gitlab::VERSION}" - puts "Revision:\t#{Gitlab::REVISION}" - puts "Directory:\t#{Rails.root}" - puts "DB Adapter:\t#{database_adapter}" - puts "URL:\t\t#{Gitlab.config.gitlab.url}" - puts "HTTP Clone URL:\t#{http_clone_url}" - puts "SSH Clone URL:\t#{ssh_clone_url}" - puts "Using LDAP:\t#{Gitlab.config.ldap.enabled ? "yes".green : "no"}" - puts "Using Omniauth:\t#{Gitlab.config.omniauth.enabled ? "yes".green : "no"}" - puts "Omniauth Providers: #{omniauth_providers.map(&:magenta).join(', ')}" if Gitlab.config.omniauth.enabled - - - - # check Gitolite version - gitlab_shell_version_file = "#{Gitlab.config.gitlab_shell.hooks_path}/../VERSION" - if File.readable?(gitlab_shell_version_file) - gitlab_shell_version = File.read(gitlab_shell_version_file) - end - - puts "" - puts "GitLab Shell".yellow - puts "Version:\t#{gitlab_shell_version || "unknown".red}" - puts "Repositories:\t#{Gitlab.config.gitlab_shell.repos_path}" - puts "Hooks:\t\t#{Gitlab.config.gitlab_shell.hooks_path}" - puts "Git:\t\t#{Gitlab.config.git.bin_path}" - - end - end -end diff --git a/lib/tasks/gitlab/mail_google_schema_whitelisting.rake b/lib/tasks/gitlab/mail_google_schema_whitelisting.rake deleted file mode 100644 index 102c6ae55d5afd9245e9234e1ddd14b683615d48..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/mail_google_schema_whitelisting.rake +++ /dev/null @@ -1,73 +0,0 @@ -require "#{Rails.root}/app/helpers/emails_helper" -require 'action_view/helpers' -extend ActionView::Helpers - -include ActionView::Context -include EmailsHelper - -namespace :gitlab do - desc "Email google whitelisting email with example email for actions in inbox" - task mail_google_schema_whitelisting: :environment do - subject = "Rails | Implemented feature" - url = "#{Gitlab.config.gitlab.url}/base/rails-project/issues/#{rand(1..100)}#note_#{rand(10..1000)}" - schema = email_action(url) - body = email_template(schema, url) - mail = Notify.test_email("schema.whitelisting+sample@gmail.com", subject, body.html_safe) - if send_now - mail.deliver - else - puts "WOULD SEND:" - end - puts mail - end - - def email_template(schema, url) - " - - - - GitLab - - - - - -
    -
    -

    I like it :+1:

    -
    -
    - - - - " - end - - def send_now - if ENV['SEND'] == "true" - true - else - false - end - end -end diff --git a/lib/tasks/gitlab/setup.rake b/lib/tasks/gitlab/setup.rake deleted file mode 100644 index 8b4ccdfc3fe01eb0b7ad8308746024c02bec7875..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/setup.rake +++ /dev/null @@ -1,24 +0,0 @@ -namespace :gitlab do - desc "GITLAB | Setup production application" - task setup: :environment do - setup_db - end - - def setup_db - warn_user_is_not_gitlab - - unless ENV['force'] == 'yes' - puts "This will create the necessary database tables and seed the database." - puts "You will lose any previous data stored in the database." - ask_to_continue - puts "" - end - - Rake::Task["db:setup"].invoke - Rake::Task["add_limits_mysql"].invoke - Rake::Task["db:seed_fu"].invoke - rescue Gitlab::TaskAbortedByUserError - puts "Quitting...".red - exit 1 - end -end diff --git a/lib/tasks/gitlab/shell.rake b/lib/tasks/gitlab/shell.rake deleted file mode 100644 index e835d6cb9b7720566838327c8448c736c9a7519e..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/shell.rake +++ /dev/null @@ -1,138 +0,0 @@ -namespace :gitlab do - namespace :shell do - desc "GITLAB | Install or upgrade gitlab-shell" - task :install, [:tag, :repo] => :environment do |t, args| - warn_user_is_not_gitlab - - default_version = Gitlab::Shell.version_required - args.with_defaults(tag: 'v' + default_version, repo: "https://gitlab.com/gitlab-org/gitlab-shell.git") - - user = Gitlab.config.gitlab.user - home_dir = Rails.env.test? ? Rails.root.join('tmp/tests') : Gitlab.config.gitlab.user_home - gitlab_url = Gitlab.config.gitlab.url - # gitlab-shell requires a / at the end of the url - gitlab_url += '/' unless gitlab_url.end_with?('/') - repos_path = Gitlab.config.gitlab_shell.repos_path - target_dir = Gitlab.config.gitlab_shell.path - - # Clone if needed - unless File.directory?(target_dir) - system(*%W(git clone -- #{args.repo} #{target_dir})) - end - - # Make sure we're on the right tag - Dir.chdir(target_dir) do - # First try to checkout without fetching - # to avoid stalling tests if the Internet is down. - reseted = reset_to_commit(args) - - unless reseted - system(*%W(git fetch origin)) - reset_to_commit(args) - end - - config = { - user: user, - gitlab_url: gitlab_url, - http_settings: {self_signed_cert: false}.stringify_keys, - repos_path: repos_path, - auth_file: File.join(home_dir, ".ssh", "authorized_keys"), - redis: { - bin: %x{which redis-cli}.chomp, - namespace: "resque:gitlab" - }.stringify_keys, - log_level: "INFO", - audit_usernames: false - }.stringify_keys - - redis_url = URI.parse(ENV['REDIS_URL'] || "redis://localhost:6379") - - if redis_url.scheme == 'unix' - config['redis']['socket'] = redis_url.path - else - config['redis']['host'] = redis_url.host - config['redis']['port'] = redis_url.port - end - - # Generate config.yml based on existing gitlab settings - File.open("config.yml", "w+") {|f| f.puts config.to_yaml} - - # Launch installation process - system(*%W(bin/install)) - end - - # Required for debian packaging with PKGR: Setup .ssh/environment with - # the current PATH, so that the correct ruby version gets loaded - # Requires to set "PermitUserEnvironment yes" in sshd config (should not - # be an issue since it is more than likely that there are no "normal" - # user accounts on a gitlab server). The alternative is for the admin to - # install a ruby (1.9.3+) in the global path. - File.open(File.join(home_dir, ".ssh", "environment"), "w+") do |f| - f.puts "PATH=#{ENV['PATH']}" - end - end - - desc "GITLAB | Setup gitlab-shell" - task setup: :environment do - setup - end - - desc "GITLAB | Build missing projects" - task build_missing_projects: :environment do - Project.find_each(batch_size: 1000) do |project| - path_to_repo = project.repository.path_to_repo - if File.exists?(path_to_repo) - print '-' - else - if Gitlab::Shell.new.add_repository(project.path_with_namespace) - print '.' - else - print 'F' - end - end - end - end - end - - def setup - warn_user_is_not_gitlab - - unless ENV['force'] == 'yes' - puts "This will rebuild an authorized_keys file." - puts "You will lose any data stored in authorized_keys file." - ask_to_continue - puts "" - end - - Gitlab::Shell.new.remove_all_keys - - Gitlab::Shell.new.batch_add_keys do |adder| - Key.find_each(batch_size: 1000) do |key| - adder.add_key(key.shell_id, key.key) - print '.' - end - end - puts "" - - unless $?.success? - puts "Failed to add keys...".red - exit 1 - end - - rescue Gitlab::TaskAbortedByUserError - puts "Quitting...".red - exit 1 - end - - def reset_to_commit(args) - tag, status = Gitlab::Popen.popen(%W(git describe -- #{args.tag})) - - unless status.zero? - tag, status = Gitlab::Popen.popen(%W(git describe -- origin/#{args.tag})) - end - - tag = tag.strip - system(*%W(git reset --hard #{tag})) - end -end - diff --git a/lib/tasks/gitlab/sidekiq.rake b/lib/tasks/gitlab/sidekiq.rake deleted file mode 100644 index 7e2a6668e592d48a6766eda9fa10412a15d55462..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/sidekiq.rake +++ /dev/null @@ -1,47 +0,0 @@ -namespace :gitlab do - namespace :sidekiq do - QUEUE = 'queue:post_receive' - - desc 'Drop all Sidekiq PostReceive jobs for a given project' - task :drop_post_receive , [:project] => :environment do |t, args| - unless args.project.present? - abort "Please specify the project you want to drop PostReceive jobs for:\n rake gitlab:sidekiq:drop_post_receive[group/project]" - end - project_path = Project.find_with_namespace(args.project).repository.path_to_repo - - Sidekiq.redis do |redis| - unless redis.exists(QUEUE) - abort "Queue #{QUEUE} is empty" - end - - temp_queue = "#{QUEUE}_#{Time.now.to_i}" - redis.rename(QUEUE, temp_queue) - - # At this point, then post_receive queue is empty. It may be receiving - # new jobs already. We will repopulate it with the old jobs, skipping the - # ones we want to drop. - dropped = 0 - while (job = redis.lpop(temp_queue)) do - if repo_path(job) == project_path - dropped += 1 - else - redis.rpush(QUEUE, job) - end - end - # The temp_queue will delete itself after we have popped all elements - # from it - - puts "Dropped #{dropped} jobs containing #{project_path} from #{QUEUE}" - end - end - - def repo_path(job) - job_args = JSON.parse(job)['args'] - if job_args - job_args.first - else - nil - end - end - end -end diff --git a/lib/tasks/gitlab/task_helpers.rake b/lib/tasks/gitlab/task_helpers.rake deleted file mode 100644 index 14a130be2ca6afbfeffe7a495dd6e720683e8ed5..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/task_helpers.rake +++ /dev/null @@ -1,131 +0,0 @@ -module Gitlab - class TaskAbortedByUserError < StandardError; end -end - -unless STDOUT.isatty - module Colored - extend self - - def colorize(string, options={}) - string - end - end -end - -namespace :gitlab do - - # Ask if the user wants to continue - # - # Returns "yes" the user chose to continue - # Raises Gitlab::TaskAbortedByUserError if the user chose *not* to continue - def ask_to_continue - answer = prompt("Do you want to continue (yes/no)? ".blue, %w{yes no}) - raise Gitlab::TaskAbortedByUserError unless answer == "yes" - end - - # Check which OS is running - # - # It will primarily use lsb_relase to determine the OS. - # It has fallbacks to Debian, SuSE, OS X and systems running systemd. - def os_name - os_name = run(%W(lsb_release -irs)) - os_name ||= if File.readable?('/etc/system-release') - File.read('/etc/system-release') - end - os_name ||= if File.readable?('/etc/debian_version') - debian_version = File.read('/etc/debian_version') - "Debian #{debian_version}" - end - os_name ||= if File.readable?('/etc/SuSE-release') - File.read('/etc/SuSE-release') - end - os_name ||= if os_x_version = run(%W(sw_vers -productVersion)) - "Mac OS X #{os_x_version}" - end - os_name ||= if File.readable?('/etc/os-release') - File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1] - end - os_name.try(:squish!) - end - - # Prompt the user to input something - # - # message - the message to display before input - # choices - array of strings of acceptable answers or nil for any answer - # - # Returns the user's answer - def prompt(message, choices = nil) - begin - print(message) - answer = STDIN.gets.chomp - end while choices.present? && !choices.include?(answer) - answer - end - - # Runs the given command and matches the output against the given pattern - # - # Returns nil if nothing matched - # Returns the MatchData if the pattern matched - # - # see also #run - # see also String#match - def run_and_match(command, regexp) - run(command).try(:match, regexp) - end - - # Runs the given command - # - # Returns nil if the command was not found - # Returns the output of the command otherwise - # - # see also #run_and_match - def run(command) - output, _ = Gitlab::Popen.popen(command) - output - rescue Errno::ENOENT - '' # if the command does not exist, return an empty string - end - - def uid_for(user_name) - run(%W(id -u #{user_name})).chomp.to_i - end - - def gid_for(group_name) - begin - Etc.getgrnam(group_name).gid - rescue ArgumentError # no group - "group #{group_name} doesn't exist" - end - end - - def warn_user_is_not_gitlab - unless @warned_user_not_gitlab - gitlab_user = Gitlab.config.gitlab.user - current_user = run(%W(whoami)).chomp - unless current_user == gitlab_user - puts "#{Colored.color(:black)+Colored.color(:on_yellow)} Warning #{Colored.extra(:clear)}" - puts " You are running as user #{current_user.magenta}, we hope you know what you are doing." - puts " Things may work\/fail for the wrong reasons." - puts " For correct results you should run this as user #{gitlab_user.magenta}." - puts "" - end - @warned_user_not_gitlab = true - end - end - - # Tries to configure git itself - # - # Returns true if all subcommands were successfull (according to their exit code) - # Returns false if any or all subcommands failed. - def auto_fix_git_config(options) - if !@warned_user_not_gitlab && options['user.email'] != 'example@example.com' # default email should be overridden? - command_success = options.map do |name, value| - system(%W(#{Gitlab.config.git.bin_path} config --global #{name} #{value})) - end - - command_success.all? - else - false - end - end -end diff --git a/lib/tasks/gitlab/test.rake b/lib/tasks/gitlab/test.rake deleted file mode 100644 index b4c0ae3ff79a5c21de9a39815c319670b234d944..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/test.rake +++ /dev/null @@ -1,16 +0,0 @@ -namespace :gitlab do - desc "GITLAB | Run all tests" - task :test do - cmds = [ - %W(rake brakeman), - %W(rake rubocop), - %W(rake spinach), - %W(rake spec), - %W(rake jasmine:ci) - ] - - cmds.each do |cmd| - system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) or raise("#{cmd} failed!") - end - end -end diff --git a/lib/tasks/gitlab/web_hook.rake b/lib/tasks/gitlab/web_hook.rake deleted file mode 100644 index f9f586db93c0c42ef56bb538bc7f78e2361754cf..0000000000000000000000000000000000000000 --- a/lib/tasks/gitlab/web_hook.rake +++ /dev/null @@ -1,65 +0,0 @@ -namespace :gitlab do - namespace :web_hook do - desc "GITLAB | Adds a web hook to the projects" - task :add => :environment do - web_hook_url = ENV['URL'] - namespace_path = ENV['NAMESPACE'] - - projects = find_projects(namespace_path) - - puts "Adding web hook '#{web_hook_url}' to:" - projects.find_each(batch_size: 1000) do |project| - print "- #{project.name} ... " - web_hook = project.hooks.new(url: web_hook_url) - if web_hook.save - puts "added".green - else - print "failed".red - puts " [#{web_hook.errors.full_messages.to_sentence}]" - end - end - end - - desc "GITLAB | Remove a web hook from the projects" - task :rm => :environment do - web_hook_url = ENV['URL'] - namespace_path = ENV['NAMESPACE'] - - projects = find_projects(namespace_path) - projects_ids = projects.pluck(:id) - - puts "Removing web hooks with the url '#{web_hook_url}' ... " - count = WebHook.where(url: web_hook_url, project_id: projects_ids, type: 'ProjectHook').delete_all - puts "#{count} web hooks were removed." - end - - desc "GITLAB | List web hooks" - task :list => :environment do - namespace_path = ENV['NAMESPACE'] - - projects = find_projects(namespace_path) - web_hooks = projects.all.map(&:hooks).flatten - web_hooks.each do |hook| - puts "#{hook.project.name.truncate(20).ljust(20)} -> #{hook.url}" - end - - puts "\n#{web_hooks.size} web hooks found." - end - end - - def find_projects(namespace_path) - if namespace_path.blank? - Project - elsif namespace_path == '/' - Project.where(namespace_id: nil) - else - namespace = Namespace.where(path: namespace_path).first - if namespace - Project.where(namespace_id: namespace.id) - else - puts "Namespace not found: #{namespace_path}".red - exit 2 - end - end - end -end diff --git a/lib/tasks/migrate/add_limits_mysql.rake b/lib/tasks/migrate/add_limits_mysql.rake deleted file mode 100644 index a1972a682d8512766e8dd6b6c6d24ab44c812461..0000000000000000000000000000000000000000 --- a/lib/tasks/migrate/add_limits_mysql.rake +++ /dev/null @@ -1,7 +0,0 @@ -require Rails.root.join('db/migrate/limits_to_mysql') - -desc "GITLAB | Add limits to strings in mysql database" -task add_limits_mysql: :environment do - puts "Adding limits to schema.rb for mysql" - LimitsToMysql.new.up -end diff --git a/lib/tasks/migrate/migrate_iids.rake b/lib/tasks/migrate/migrate_iids.rake deleted file mode 100644 index 33271e1a2bbf55baa14ad703a7a98a86d46061f8..0000000000000000000000000000000000000000 --- a/lib/tasks/migrate/migrate_iids.rake +++ /dev/null @@ -1,48 +0,0 @@ -desc "GITLAB | Build internal ids for issues and merge requests" -task migrate_iids: :environment do - puts 'Issues'.yellow - Issue.where(iid: nil).find_each(batch_size: 100) do |issue| - begin - issue.set_iid - if issue.update_attribute(:iid, issue.iid) - print '.' - else - print 'F' - end - rescue - print 'F' - end - end - - puts 'done' - puts 'Merge Requests'.yellow - MergeRequest.where(iid: nil).find_each(batch_size: 100) do |mr| - begin - mr.set_iid - if mr.update_attribute(:iid, mr.iid) - print '.' - else - print 'F' - end - rescue => ex - print 'F' - end - end - - puts 'done' - puts 'Milestones'.yellow - Milestone.where(iid: nil).find_each(batch_size: 100) do |m| - begin - m.set_iid - if m.update_attribute(:iid, m.iid) - print '.' - else - print 'F' - end - rescue - print 'F' - end - end - - puts 'done' -end diff --git a/lib/tasks/rubocop.rake b/lib/tasks/rubocop.rake deleted file mode 100644 index ddfaf5d51f281225a717c4fe8ef4e8ce4dc1a0e7..0000000000000000000000000000000000000000 --- a/lib/tasks/rubocop.rake +++ /dev/null @@ -1,4 +0,0 @@ -unless Rails.env.production? - require 'rubocop/rake_task' - RuboCop::RakeTask.new -end diff --git a/lib/tasks/setup.rake b/lib/tasks/setup.rake deleted file mode 100644 index 93701de8f6309ff9643fcdde9bfa9c653c113b6b..0000000000000000000000000000000000000000 --- a/lib/tasks/setup.rake +++ /dev/null @@ -1,4 +0,0 @@ -desc "GITLAB | Setup gitlab db" -task :setup do - Rake::Task["gitlab:setup"].invoke -end diff --git a/lib/tasks/sidekiq.rake b/lib/tasks/sidekiq.rake deleted file mode 100644 index e4bd6545755f27cce8f190e6c1dfa0564399bccd..0000000000000000000000000000000000000000 --- a/lib/tasks/sidekiq.rake +++ /dev/null @@ -1,21 +0,0 @@ -namespace :sidekiq do - desc "GITLAB | Stop sidekiq" - task :stop do - system *%W(bin/background_jobs stop) - end - - desc "GITLAB | Start sidekiq" - task :start do - system *%W(bin/background_jobs start) - end - - desc 'GitLab | Restart sidekiq' - task :restart do - system *%W(bin/background_jobs restart) - end - - desc "GITLAB | Start sidekiq with launchd on Mac OS X" - task :launchd do - system *%W(bin/background_jobs start_no_deamonize) - end -end diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake deleted file mode 100644 index bee22300298156266b6797a5988b5bce47da3abe..0000000000000000000000000000000000000000 --- a/lib/tasks/spec.rake +++ /dev/null @@ -1,45 +0,0 @@ -Rake::Task["spec"].clear if Rake::Task.task_defined?('spec') - -namespace :spec do - desc 'GITLAB | Run request specs' - task :api do - cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag @api) - ] - run_commands(cmds) - end - - desc 'GITLAB | Run feature specs' - task :feature do - cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag @feature) - ] - run_commands(cmds) - end - - desc 'GITLAB | Run other specs' - task :other do - cmds = [ - %W(rake gitlab:setup), - %W(rspec spec --tag ~@api --tag ~@feature) - ] - run_commands(cmds) - end -end - -desc "GITLAB | Run specs" -task :spec do - cmds = [ - %W(rake gitlab:setup), - %W(rspec spec), - ] - run_commands(cmds) -end - -def run_commands(cmds) - cmds.each do |cmd| - system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) or raise("#{cmd} failed!") - end -end diff --git a/lib/tasks/spinach.rake b/lib/tasks/spinach.rake deleted file mode 100644 index 4aefc18ce1481b9c98754a17239ac5e16d226d57..0000000000000000000000000000000000000000 --- a/lib/tasks/spinach.rake +++ /dev/null @@ -1,40 +0,0 @@ -Rake::Task["spinach"].clear if Rake::Task.task_defined?('spinach') - -desc "GITLAB | Run spinach" -task :spinach do - tags = if ENV['SEMAPHORE'] - '~@tricky' - else - '~@semaphore' - end - - cmds = [ - %W(rake gitlab:setup), - %W(spinach --tags #{tags}), - ] - run_commands(cmds) -end - -desc "GITLAB | Run project spinach features" -task :spinach_project do - cmds = [ - %W(rake gitlab:setup), - %W(spinach --tags ~@admin,~@dashboard,~@profile,~@public,~@snippets), - ] - run_commands(cmds) -end - -desc "GITLAB | Run other spinach features" -task :spinach_other do - cmds = [ - %W(rake gitlab:setup), - %W(spinach --tags @admin,@dashboard,@profile,@public,@snippets), - ] - run_commands(cmds) -end - -def run_commands(cmds) - cmds.each do |cmd| - system({'RAILS_ENV' => 'test', 'force' => 'yes'}, *cmd) or raise("#{cmd} failed!") - end -end diff --git a/lib/tasks/test.rake b/lib/tasks/test.rake deleted file mode 100644 index a39d96498761113bae71077a64a7e02510dbe35f..0000000000000000000000000000000000000000 --- a/lib/tasks/test.rake +++ /dev/null @@ -1,13 +0,0 @@ -Rake::Task["test"].clear - -desc "GITLAB | Run all tests" -task :test do - Rake::Task["gitlab:test"].invoke -end - -unless Rails.env.production? - require 'coveralls/rake/task' - Coveralls::RakeTask.new - desc "GITLAB | Run all tests on CI with simplecov" - task :test_ci => [:rubocop, :brakeman, 'jasmine:ci', :spinach, :spec, 'coveralls:push'] -end diff --git a/lib/unfold_form.rb b/lib/unfold_form.rb deleted file mode 100644 index 46b12beeaaf364bd50c6dff38c43ee33bdbafe88..0000000000000000000000000000000000000000 --- a/lib/unfold_form.rb +++ /dev/null @@ -1,11 +0,0 @@ -require_relative 'gt_one_coercion' - -class UnfoldForm - include Virtus.model - - attribute :since, GtOneCoercion - attribute :to, GtOneCoercion - attribute :bottom, Boolean - attribute :unfold, Boolean, default: true - attribute :offset, Integer -end diff --git a/log/.gitkeep b/log/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/public/404.html b/public/404.html deleted file mode 100644 index 867f193a98f573e65a69b336c8205ea392c84c0e..0000000000000000000000000000000000000000 --- a/public/404.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - The page you were looking for doesn't exist (404) - - - - -

    404

    -

    The page you were looking for doesn't exist.

    -
    -

    You may have mistyped the address or the page may have moved.

    - - diff --git a/public/422.html b/public/422.html deleted file mode 100644 index b6c37ac53866f33aabea2b79ebc365053dbe8e77..0000000000000000000000000000000000000000 --- a/public/422.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - The change you wanted was rejected (422) - - - - - -

    422

    -
    -

    The change you wanted was rejected.

    -

    Maybe you tried to change something you didn't have access to.

    -
    - - diff --git a/public/500.html b/public/500.html deleted file mode 100644 index c84b9e90e4bee2666f5cb3688690d9824d88f3ee..0000000000000000000000000000000000000000 --- a/public/500.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - We're sorry, but something went wrong (500) - - - -

    500

    -

    We're sorry, but something went wrong.

    -
    -

    Please contact your GitLab administrator if this problem persists.

    - - diff --git a/public/502.html b/public/502.html deleted file mode 100644 index d171eccc92794792253ca82a607c9be9f3b235f9..0000000000000000000000000000000000000000 --- a/public/502.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - GitLab is not responding (502) - - - -

    502

    -

    GitLab is not responding.

    -
    -

    Please contact your GitLab administrator if this problem persists.

    - - diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png deleted file mode 100644 index 6f2e0dd090ff597a7261de7b8b7d403a92691a51..0000000000000000000000000000000000000000 Binary files a/public/apple-touch-icon-precomposed.png and /dev/null differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png deleted file mode 100644 index 6f2e0dd090ff597a7261de7b8b7d403a92691a51..0000000000000000000000000000000000000000 Binary files a/public/apple-touch-icon.png and /dev/null differ diff --git a/public/deploy.html b/public/deploy.html deleted file mode 100644 index d9c4bb5c5833038732b13f7f69641978b09c512d..0000000000000000000000000000000000000000 --- a/public/deploy.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - Deploy in progress. Please try again in few minutes - - - -

    Deploy in progress

    -

    Please try again in few minutes or contact your administrator.

    - - diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index bfb74960c480e6cb14f1d38437303af6b375ccaf..0000000000000000000000000000000000000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/gitlab_logo.png b/public/gitlab_logo.png deleted file mode 100644 index dbe6dabb784f3f104908e2eefe79a887545d1075..0000000000000000000000000000000000000000 Binary files a/public/gitlab_logo.png and /dev/null differ diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index 085187fa58b1631e955f5d514d895a7721466797..0000000000000000000000000000000000000000 --- a/public/robots.txt +++ /dev/null @@ -1,5 +0,0 @@ -# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: -# User-Agent: * -# Disallow: / diff --git a/public/static.css b/public/static.css deleted file mode 100644 index c6f92ac01d90897ad9fd97c41ae715137d92d38d..0000000000000000000000000000000000000000 --- a/public/static.css +++ /dev/null @@ -1,30 +0,0 @@ -body { - color: #666; - text-align: center; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - margin:0; - width: 800px; - margin: auto; - font-size: 14px; -} -h1 { - font-size: 56px; - line-height: 100px; - font-weight: normal; - color: #456; -} -h2 { font-size: 24px; color: #666; line-height: 1.5em; } - -h3 { - color: #456; - font-size: 20px; - font-weight: normal; - line-height: 28px; -} - -hr { - margin: 18px 0; - border: 0; - border-top: 1px solid #EEE; - border-bottom: 1px solid white; -} diff --git a/public/uploads/.gitkeep b/public/uploads/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/safe/public.pem b/safe/public.pem deleted file mode 100644 index c5ffe20a5c7bc19f5addf5e4aac0d9f099bcab19..0000000000000000000000000000000000000000 --- a/safe/public.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnp2mUaLBoHFX127ysonX -OihiGpI4098eFfH1iAxpKHIof0vs0jFF05IUScNXJZ1U3w8G1U/unY/wGGa3NzAb -ZfDd22eOF6X2Gfiey6U4w9dFf0/UT5x1bphlpX357yh4O9oWWuNaWD062DTbOOsJ -U6UW2U/sZAu/QScys0Nw+gJ58t93hb4jFq+nO5IAQc6g4S8ek5YvIXOshFEpF2in -ZLbSYowx92+9GzfjvdQ7fk0Q2ssg0zfScVa6FY8n019osz0SC3wcSd/qicdfecpu -7oycpd9YDqk4lufE1qVMOsgE8OO4KXMrByz2f+T0p/bH9zdBa5HYylf1T7i60hIL -kQIDAQAB ------END PUBLIC KEY----- diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb deleted file mode 100644 index 186239d3096b6a548b41d8bf0348e446986f3380..0000000000000000000000000000000000000000 --- a/spec/controllers/application_controller_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'spec_helper' - -describe ApplicationController do - describe '#check_password_expiration' do - let(:user) { create(:user) } - let(:controller) { ApplicationController.new } - - it 'should redirect if the user is over their password expiry' do - user.password_expires_at = Time.new(2002) - expect(user.ldap_user?).to be_falsey - allow(controller).to receive(:current_user).and_return(user) - expect(controller).to receive(:redirect_to) - expect(controller).to receive(:new_profile_password_path) - controller.send(:check_password_expiration) - end - - it 'should not redirect if the user is under their password expiry' do - user.password_expires_at = Time.now + 20010101 - expect(user.ldap_user?).to be_falsey - allow(controller).to receive(:current_user).and_return(user) - expect(controller).not_to receive(:redirect_to) - controller.send(:check_password_expiration) - end - - it 'should not redirect if the user is over their password expiry but they are an ldap user' do - user.password_expires_at = Time.new(2002) - allow(user).to receive(:ldap_user?).and_return(true) - allow(controller).to receive(:current_user).and_return(user) - expect(controller).not_to receive(:redirect_to) - controller.send(:check_password_expiration) - end - end -end diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb deleted file mode 100644 index a0909cec3bd6f77f916aa1e86b9284441e1b8ecc..0000000000000000000000000000000000000000 --- a/spec/controllers/autocomplete_controller_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'spec_helper' - -describe AutocompleteController do - let!(:project) { create(:project) } - let!(:user) { create(:user) } - let!(:user2) { create(:user) } - - context 'project members' do - before do - sign_in(user) - project.team << [user, :master] - - get(:users, project_id: project.id) - end - - let(:body) { JSON.parse(response.body) } - - it { body.should be_kind_of(Array) } - it { body.size.should eq(1) } - it { body.first["username"].should == user.username } - end - - context 'group members' do - let(:group) { create(:group) } - - before do - sign_in(user) - group.add_owner(user) - - get(:users, group_id: group.id) - end - - let(:body) { JSON.parse(response.body) } - - it { body.should be_kind_of(Array) } - it { body.size.should eq(1) } - it { body.first["username"].should == user.username } - end - - context 'all users' do - before do - sign_in(user) - get(:users) - end - - let(:body) { JSON.parse(response.body) } - - it { body.should be_kind_of(Array) } - it { body.size.should eq(User.count) } - end -end diff --git a/spec/controllers/blob_controller_spec.rb b/spec/controllers/blob_controller_spec.rb deleted file mode 100644 index a1102f283406ca24dca53a0787ecdb3f48de08c2..0000000000000000000000000000000000000000 --- a/spec/controllers/blob_controller_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'spec_helper' - -describe Projects::BlobController do - let(:project) { create(:project) } - let(:user) { create(:user) } - - before do - sign_in(user) - - project.team << [user, :master] - - allow(project).to receive(:branches).and_return(['master', 'foo/bar/baz']) - allow(project).to receive(:tags).and_return(['v1.0.0', 'v2.0.0']) - controller.instance_variable_set(:@project, project) - end - - describe "GET show" do - render_views - - before do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: id) - end - - context "valid branch, valid file" do - let(:id) { 'master/README.md' } - it { is_expected.to respond_with(:success) } - end - - context "valid branch, invalid file" do - let(:id) { 'master/invalid-path.rb' } - it { is_expected.to respond_with(:not_found) } - end - - context "invalid branch, valid file" do - let(:id) { 'invalid-branch/README.md' } - it { is_expected.to respond_with(:not_found) } - end - end - - describe 'GET show with tree path' do - render_views - - before do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: id) - controller.instance_variable_set(:@blob, nil) - end - - context 'redirect to tree' do - let(:id) { 'markdown/doc' } - it 'redirects' do - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/markdown/doc") - end - end - end -end diff --git a/spec/controllers/branches_controller_spec.rb b/spec/controllers/branches_controller_spec.rb deleted file mode 100644 index 51397382cfbc107fc8cd4caf658195b078c4f631..0000000000000000000000000000000000000000 --- a/spec/controllers/branches_controller_spec.rb +++ /dev/null @@ -1,58 +0,0 @@ -require 'spec_helper' - -describe Projects::BranchesController do - let(:project) { create(:project) } - let(:user) { create(:user) } - - before do - sign_in(user) - - project.team << [user, :master] - - allow(project).to receive(:branches).and_return(['master', 'foo/bar/baz']) - allow(project).to receive(:tags).and_return(['v1.0.0', 'v2.0.0']) - controller.instance_variable_set(:@project, project) - end - - describe "POST create" do - render_views - - before { - post :create, - namespace_id: project.namespace.to_param, - project_id: project.to_param, - branch_name: branch, - ref: ref - } - - context "valid branch name, valid source" do - let(:branch) { "merge_branch" } - let(:ref) { "master" } - it 'redirects' do - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/merge_branch") - end - end - - context "invalid branch name, valid ref" do - let(:branch) { "" } - let(:ref) { "master" } - it 'redirects' do - expect(subject). - to redirect_to("/#{project.path_with_namespace}/tree/alert('merge');") - end - end - - context "valid branch name, invalid ref" do - let(:branch) { "merge_branch" } - let(:ref) { "" } - it { is_expected.to render_template('new') } - end - - context "invalid branch name, invalid ref" do - let(:branch) { "" } - let(:ref) { "" } - it { is_expected.to render_template('new') } - end - end -end diff --git a/spec/controllers/commit_controller_spec.rb b/spec/controllers/commit_controller_spec.rb deleted file mode 100644 index 3394a1f863fa1f12477a2ea0466c186e14120a12..0000000000000000000000000000000000000000 --- a/spec/controllers/commit_controller_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -require 'spec_helper' - -describe Projects::CommitController do - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:commit) { project.repository.commit("master") } - - before do - sign_in(user) - project.team << [user, :master] - end - - describe "#show" do - shared_examples "export as" do |format| - it "should generally work" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: commit.id, format: format) - - expect(response).to be_success - end - - it "should generate it" do - expect_any_instance_of(Commit).to receive(:"to_#{format}") - - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: commit.id, format: format) - end - - it "should render it" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: commit.id, format: format) - - expect(response.body).to eq(commit.send(:"to_#{format}")) - end - - it "should not escape Html" do - allow_any_instance_of(Commit).to receive(:"to_#{format}"). - and_return('HTML entities &<>" ') - - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: commit.id, format: format) - - expect(response.body).to_not include('&') - expect(response.body).to_not include('>') - expect(response.body).to_not include('<') - expect(response.body).to_not include('"') - end - end - - describe "as diff" do - include_examples "export as", :diff - let(:format) { :diff } - - it "should really only be a git diff" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: commit.id, format: format) - - expect(response.body).to start_with("diff --git") - end - end - - describe "as patch" do - include_examples "export as", :patch - let(:format) { :patch } - - it "should really be a git email patch" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: commit.id, format: format) - - expect(response.body).to start_with("From #{commit.id}") - end - - it "should contain a git diff" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: commit.id, format: format) - - expect(response.body).to match(/^diff --git/) - end - end - end - - describe "#branches" do - it "contains branch and tags information" do - get(:branches, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: commit.id) - - expect(assigns(:branches)).to include("master", "feature_conflict") - expect(assigns(:tags)).to include("v1.1.0") - end - end -end diff --git a/spec/controllers/commits_controller_spec.rb b/spec/controllers/commits_controller_spec.rb deleted file mode 100644 index 2184b35152eadfb20740aba0b8a3908a9d09c37a..0000000000000000000000000000000000000000 --- a/spec/controllers/commits_controller_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' - -describe Projects::CommitsController do - let(:project) { create(:project) } - let(:user) { create(:user) } - - before do - sign_in(user) - project.team << [user, :master] - end - - describe "GET show" do - context "as atom feed" do - it "should render as atom" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: "master", format: "atom") - expect(response).to be_success - expect(response.content_type).to eq('application/atom+xml') - end - end - end -end diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb deleted file mode 100644 index c31563e6d77c55d7de57214ebe76bfe4ff95f6ef..0000000000000000000000000000000000000000 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ /dev/null @@ -1,163 +0,0 @@ -require 'spec_helper' - -describe Import::BitbucketController do - let(:user) { create(:user, bitbucket_access_token: 'asd123', bitbucket_access_token_secret: "sekret") } - - before do - sign_in(user) - controller.stub(:bitbucket_import_enabled?).and_return(true) - end - - describe "GET callback" do - before do - session[:oauth_request_token] = {} - end - - it "updates access token" do - token = "asdasd12345" - secret = "sekrettt" - access_token = double(token: token, secret: secret) - Gitlab::BitbucketImport::Client.any_instance.stub(:get_token).and_return(access_token) - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "bitbucket") - - get :callback - - expect(user.reload.bitbucket_access_token).to eq(token) - expect(user.reload.bitbucket_access_token_secret).to eq(secret) - expect(controller).to redirect_to(status_import_bitbucket_url) - end - end - - describe "GET status" do - before do - @repo = OpenStruct.new(slug: 'vim', owner: 'asd') - end - - it "assigns variables" do - @project = create(:project, import_type: 'bitbucket', creator_id: user.id) - controller.stub_chain(:client, :projects).and_return([@repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([@repo]) - end - - it "does not show already added project" do - @project = create(:project, import_type: 'bitbucket', creator_id: user.id, import_source: 'asd/vim') - controller.stub_chain(:client, :projects).and_return([@repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([]) - end - end - - describe "POST create" do - let(:bitbucket_username) { user.username } - - let(:bitbucket_user) { - { - user: { - username: bitbucket_username - } - }.with_indifferent_access - } - - let(:bitbucket_repo) { - { - slug: "vim", - owner: bitbucket_username - }.with_indifferent_access - } - - before do - allow(Gitlab::BitbucketImport::KeyAdder). - to receive(:new).with(bitbucket_repo, user). - and_return(double(execute: true)) - - controller.stub_chain(:client, :user).and_return(bitbucket_user) - controller.stub_chain(:client, :project).and_return(bitbucket_repo) - end - - context "when the repository owner is the Bitbucket user" do - context "when the Bitbucket user and GitLab user's usernames match" do - it "takes the current user's namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, user.namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - - context "when the Bitbucket user and GitLab user's usernames don't match" do - let(:bitbucket_username) { "someone_else" } - - it "takes the current user's namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, user.namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - - context "when the repository owner is not the Bitbucket user" do - let(:other_username) { "someone_else" } - - before do - bitbucket_repo["owner"] = other_username - end - - context "when a namespace with the Bitbucket user's username already exists" do - let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } - - context "when the namespace is owned by the GitLab user" do - it "takes the existing namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, existing_namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - - context "when the namespace is not owned by the GitLab user" do - before do - existing_namespace.owner = create(:user) - existing_namespace.save - end - - it "doesn't create a project" do - expect(Gitlab::BitbucketImport::ProjectCreator). - not_to receive(:new) - - post :create, format: :js - end - end - end - - context "when a namespace with the Bitbucket user's username doesn't exist" do - it "creates the namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) - - post :create, format: :js - - expect(Namespace.where(name: other_username).first).not_to be_nil - end - - it "takes the new namespace" do - expect(Gitlab::BitbucketImport::ProjectCreator). - to receive(:new).with(bitbucket_repo, an_instance_of(Group), user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - end -end diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb deleted file mode 100644 index 3d3846b2e3a9a6fd42b0d5ce627993ad537447d3..0000000000000000000000000000000000000000 --- a/spec/controllers/import/github_controller_spec.rb +++ /dev/null @@ -1,153 +0,0 @@ -require 'spec_helper' - -describe Import::GithubController do - let(:user) { create(:user, github_access_token: 'asd123') } - - before do - sign_in(user) - controller.stub(:github_import_enabled?).and_return(true) - end - - describe "GET callback" do - it "updates access token" do - token = "asdasd12345" - allow_any_instance_of(Gitlab::GithubImport::Client). - to receive(:get_token).and_return(token) - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: 'asd123', - app_secret: 'asd123', - name: 'github') - - get :callback - - expect(user.reload.github_access_token).to eq(token) - expect(controller).to redirect_to(status_import_github_url) - end - end - - describe "GET status" do - before do - @repo = OpenStruct.new(login: 'vim', full_name: 'asd/vim') - @org = OpenStruct.new(login: 'company') - @org_repo = OpenStruct.new(login: 'company', full_name: 'company/repo') - end - - it "assigns variables" do - @project = create(:project, import_type: 'github', creator_id: user.id) - controller.stub_chain(:client, :repos).and_return([@repo]) - controller.stub_chain(:client, :orgs).and_return([@org]) - controller.stub_chain(:client, :org_repos).with(@org.login).and_return([@org_repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([@repo, @org_repo]) - end - - it "does not show already added project" do - @project = create(:project, import_type: 'github', creator_id: user.id, import_source: 'asd/vim') - controller.stub_chain(:client, :repos).and_return([@repo]) - controller.stub_chain(:client, :orgs).and_return([]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([]) - end - end - - describe "POST create" do - let(:github_username) { user.username } - - let(:github_user) { - OpenStruct.new(login: github_username) - } - - let(:github_repo) { - OpenStruct.new(name: 'vim', full_name: "#{github_username}/vim", owner: OpenStruct.new(login: github_username)) - } - - before do - controller.stub_chain(:client, :user).and_return(github_user) - controller.stub_chain(:client, :repo).and_return(github_repo) - end - - context "when the repository owner is the GitHub user" do - context "when the GitHub user and GitLab user's usernames match" do - it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(github_repo, user.namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - - context "when the GitHub user and GitLab user's usernames don't match" do - let(:github_username) { "someone_else" } - - it "takes the current user's namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(github_repo, user.namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - - context "when the repository owner is not the GitHub user" do - let(:other_username) { "someone_else" } - - before do - github_repo.owner = OpenStruct.new(login: other_username) - end - - context "when a namespace with the GitHub user's username already exists" do - let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } - - context "when the namespace is owned by the GitLab user" do - it "takes the existing namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(github_repo, existing_namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - - context "when the namespace is not owned by the GitLab user" do - before do - existing_namespace.owner = create(:user) - existing_namespace.save - end - - it "doesn't create a project" do - expect(Gitlab::GithubImport::ProjectCreator). - not_to receive(:new) - - post :create, format: :js - end - end - end - - context "when a namespace with the GitHub user's username doesn't exist" do - it "creates the namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) - - post :create, format: :js - - expect(Namespace.where(name: other_username).first).not_to be_nil - end - - it "takes the new namespace" do - expect(Gitlab::GithubImport::ProjectCreator). - to receive(:new).with(github_repo, an_instance_of(Group), user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - end -end diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb deleted file mode 100644 index 112e51d431ecf40570e8f26cf79dc580b6311f7d..0000000000000000000000000000000000000000 --- a/spec/controllers/import/gitlab_controller_spec.rb +++ /dev/null @@ -1,152 +0,0 @@ -require 'spec_helper' - -describe Import::GitlabController do - let(:user) { create(:user, gitlab_access_token: 'asd123') } - - before do - sign_in(user) - controller.stub(:gitlab_import_enabled?).and_return(true) - end - - describe "GET callback" do - it "updates access token" do - token = "asdasd12345" - Gitlab::GitlabImport::Client.any_instance.stub_chain(:client, :auth_code, :get_token, :token).and_return(token) - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "gitlab") - - get :callback - - expect(user.reload.gitlab_access_token).to eq(token) - expect(controller).to redirect_to(status_import_gitlab_url) - end - end - - describe "GET status" do - before do - @repo = OpenStruct.new(path: 'vim', path_with_namespace: 'asd/vim') - end - - it "assigns variables" do - @project = create(:project, import_type: 'gitlab', creator_id: user.id) - controller.stub_chain(:client, :projects).and_return([@repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([@repo]) - end - - it "does not show already added project" do - @project = create(:project, import_type: 'gitlab', creator_id: user.id, import_source: 'asd/vim') - controller.stub_chain(:client, :projects).and_return([@repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([]) - end - end - - describe "POST create" do - let(:gitlab_username) { user.username } - - let(:gitlab_user) { - { - username: gitlab_username - }.with_indifferent_access - } - - let(:gitlab_repo) { - { - path: 'vim', - path_with_namespace: "#{gitlab_username}/vim", - owner: { name: gitlab_username }, - namespace: { path: gitlab_username } - }.with_indifferent_access - } - - before do - controller.stub_chain(:client, :user).and_return(gitlab_user) - controller.stub_chain(:client, :project).and_return(gitlab_repo) - end - - context "when the repository owner is the GitLab.com user" do - context "when the GitLab.com user and GitLab server user's usernames match" do - it "takes the current user's namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, user.namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - - context "when the GitLab.com user and GitLab server user's usernames don't match" do - let(:gitlab_username) { "someone_else" } - - it "takes the current user's namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, user.namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - - context "when the repository owner is not the GitLab.com user" do - let(:other_username) { "someone_else" } - - before do - gitlab_repo["namespace"]["path"] = other_username - end - - context "when a namespace with the GitLab.com user's username already exists" do - let!(:existing_namespace) { create(:namespace, name: other_username, owner: user) } - - context "when the namespace is owned by the GitLab server user" do - it "takes the existing namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, existing_namespace, user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - - context "when the namespace is not owned by the GitLab server user" do - before do - existing_namespace.owner = create(:user) - existing_namespace.save - end - - it "doesn't create a project" do - expect(Gitlab::GitlabImport::ProjectCreator). - not_to receive(:new) - - post :create, format: :js - end - end - end - - context "when a namespace with the GitLab.com user's username doesn't exist" do - it "creates the namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).and_return(double(execute: true)) - - post :create, format: :js - - expect(Namespace.where(name: other_username).first).not_to be_nil - end - - it "takes the new namespace" do - expect(Gitlab::GitlabImport::ProjectCreator). - to receive(:new).with(gitlab_repo, an_instance_of(Group), user). - and_return(double(execute: true)) - - post :create, format: :js - end - end - end - end -end diff --git a/spec/controllers/import/gitorious_controller_spec.rb b/spec/controllers/import/gitorious_controller_spec.rb deleted file mode 100644 index 07c9484bf1a2fafa2e98ccb64b0546dbcb5718d4..0000000000000000000000000000000000000000 --- a/spec/controllers/import/gitorious_controller_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -require 'spec_helper' - -describe Import::GitoriousController do - let(:user) { create(:user) } - - before do - sign_in(user) - end - - describe "GET new" do - it "redirects to import endpoint on gitorious.org" do - get :new - - expect(controller).to redirect_to("https://gitorious.org/gitlab-import?callback_url=http://test.host/import/gitorious/callback") - end - end - - describe "GET callback" do - it "stores repo list in session" do - get :callback, repos: 'foo/bar,baz/qux' - - expect(session[:gitorious_repos]).to eq('foo/bar,baz/qux') - end - end - - describe "GET status" do - before do - @repo = OpenStruct.new(full_name: 'asd/vim') - end - - it "assigns variables" do - @project = create(:project, import_type: 'gitorious', creator_id: user.id) - controller.stub_chain(:client, :repos).and_return([@repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([@repo]) - end - - it "does not show already added project" do - @project = create(:project, import_type: 'gitorious', creator_id: user.id, import_source: 'asd/vim') - controller.stub_chain(:client, :repos).and_return([@repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([]) - end - end - - describe "POST create" do - before do - @repo = Gitlab::GitoriousImport::Repository.new('asd/vim') - end - - it "takes already existing namespace" do - namespace = create(:namespace, name: "asd", owner: user) - expect(Gitlab::GitoriousImport::ProjectCreator). - to receive(:new).with(@repo, namespace, user). - and_return(double(execute: true)) - controller.stub_chain(:client, :repo).and_return(@repo) - - post :create, format: :js - end - end -end diff --git a/spec/controllers/import/google_code_controller_spec.rb b/spec/controllers/import/google_code_controller_spec.rb deleted file mode 100644 index 037cddb460020c34af6a489de6707f0a86f02fd6..0000000000000000000000000000000000000000 --- a/spec/controllers/import/google_code_controller_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'spec_helper' - -describe Import::GoogleCodeController do - let(:user) { create(:user) } - let(:dump_file) { fixture_file_upload(Rails.root + 'spec/fixtures/GoogleCodeProjectHosting.json', 'application/json') } - - before do - sign_in(user) - end - - describe "POST callback" do - it "stores Google Takeout dump list in session" do - post :callback, dump_file: dump_file - - expect(session[:google_code_dump]).to be_a(Hash) - expect(session[:google_code_dump]["kind"]).to eq("projecthosting#user") - expect(session[:google_code_dump]).to have_key("projects") - end - end - - describe "GET status" do - before do - @repo = OpenStruct.new(name: 'vim') - controller.stub_chain(:client, :valid?).and_return(true) - end - - it "assigns variables" do - @project = create(:project, import_type: 'google_code', creator_id: user.id) - controller.stub_chain(:client, :repos).and_return([@repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([@repo]) - end - - it "does not show already added project" do - @project = create(:project, import_type: 'google_code', creator_id: user.id, import_source: 'vim') - controller.stub_chain(:client, :repos).and_return([@repo]) - - get :status - - expect(assigns(:already_added_projects)).to eq([@project]) - expect(assigns(:repos)).to eq([]) - end - end -end diff --git a/spec/controllers/merge_requests_controller_spec.rb b/spec/controllers/merge_requests_controller_spec.rb deleted file mode 100644 index d6f56ed33d69ba73ff1d66049dbe815b794459c3..0000000000000000000000000000000000000000 --- a/spec/controllers/merge_requests_controller_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -require 'spec_helper' - -describe Projects::MergeRequestsController do - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } - - before do - sign_in(user) - project.team << [user, :master] - end - - describe "#show" do - shared_examples "export merge as" do |format| - it "should generally work" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: merge_request.iid, format: format) - - expect(response).to be_success - end - - it "should generate it" do - expect_any_instance_of(MergeRequest).to receive(:"to_#{format}") - - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: merge_request.iid, format: format) - end - - it "should render it" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: merge_request.iid, format: format) - - expect(response.body).to eq((merge_request.send(:"to_#{format}",user)).to_s) - end - - it "should not escape Html" do - allow_any_instance_of(MergeRequest).to receive(:"to_#{format}"). - and_return('HTML entities &<>" ') - - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: merge_request.iid, format: format) - - expect(response.body).to_not include('&') - expect(response.body).to_not include('>') - expect(response.body).to_not include('<') - expect(response.body).to_not include('"') - end - end - - describe "as diff" do - include_examples "export merge as", :diff - let(:format) { :diff } - - it "should really only be a git diff" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: merge_request.iid, format: format) - - expect(response.body).to start_with("diff --git") - end - end - - describe "as patch" do - include_examples "export merge as", :patch - let(:format) { :patch } - - it "should really be a git email patch with commit" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: merge_request.iid, format: format) - - expect(response.body[0..100]).to start_with("From #{merge_request.commits.last.id}") - end - - it "should contain git diffs" do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: merge_request.iid, format: format) - - expect(response.body).to match(/^diff --git/) - end - end - end -end diff --git a/spec/controllers/namespaces_controller_spec.rb b/spec/controllers/namespaces_controller_spec.rb deleted file mode 100644 index 9c8619722cd967e5bdcde87b42e0e5ca77dbf921..0000000000000000000000000000000000000000 --- a/spec/controllers/namespaces_controller_spec.rb +++ /dev/null @@ -1,121 +0,0 @@ -require 'spec_helper' - -describe NamespacesController do - let!(:user) { create(:user, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) } - - describe "GET show" do - context "when the namespace belongs to a user" do - let!(:other_user) { create(:user) } - - it "redirects to the user's page" do - get :show, id: other_user.username - - expect(response).to redirect_to(user_path(other_user)) - end - end - - context "when the namespace belongs to a group" do - let!(:group) { create(:group) } - let!(:project) { create(:project, namespace: group) } - - context "when the group has public projects" do - before do - project.update_attribute(:visibility_level, Project::PUBLIC) - end - - context "when not signed in" do - it "redirects to the group's page" do - get :show, id: group.path - - expect(response).to redirect_to(group_path(group)) - end - end - - context "when signed in" do - before do - sign_in(user) - end - - it "redirects to the group's page" do - get :show, id: group.path - - expect(response).to redirect_to(group_path(group)) - end - end - end - - context "when the project doesn't have public projects" do - context "when not signed in" do - it "redirects to the sign in page" do - get :show, id: group.path - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when signed in" do - before do - sign_in(user) - end - - context "when the user has access to the project" do - before do - project.team << [user, :master] - end - - context "when the user is blocked" do - before do - user.block - project.team << [user, :master] - end - - it "redirects to the sign in page" do - get :show, id: group.path - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when the user isn't blocked" do - it "redirects to the group's page" do - get :show, id: group.path - - expect(response).to redirect_to(group_path(group)) - end - end - end - - context "when the user doesn't have access to the project" do - it "responds with status 404" do - get :show, id: group.path - - expect(response.status).to eq(404) - end - end - end - end - end - - context "when the namespace doesn't exist" do - context "when signed in" do - before do - sign_in(user) - end - - it "responds with status 404" do - get :show, id: "doesntexist" - - expect(response.status).to eq(404) - end - end - - context "when not signed in" do - it "redirects to the sign in page" do - get :show, id: "doesntexist" - - expect(response).to redirect_to(new_user_session_path) - end - end - end - end -end diff --git a/spec/controllers/profile_keys_controller_spec.rb b/spec/controllers/profile_keys_controller_spec.rb deleted file mode 100644 index 593d3e9eb56af120129125ae213e2e668838857c..0000000000000000000000000000000000000000 --- a/spec/controllers/profile_keys_controller_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -require 'spec_helper' - -describe Profiles::KeysController do - let(:user) { create(:user) } - - describe "#get_keys" do - describe "non existant user" do - it "should generally not work" do - get :get_keys, username: 'not-existent' - - expect(response).not_to be_success - end - end - - describe "user with no keys" do - it "should generally work" do - get :get_keys, username: user.username - - expect(response).to be_success - end - - it "should render all keys separated with a new line" do - get :get_keys, username: user.username - - expect(response.body).to eq("") - end - - it "should respond with text/plain content type" do - get :get_keys, username: user.username - expect(response.content_type).to eq("text/plain") - end - end - - describe "user with keys" do - before do - user.keys << create(:key) - user.keys << create(:another_key) - end - - it "should generally work" do - get :get_keys, username: user.username - - expect(response).to be_success - end - - it "should render all keys separated with a new line" do - get :get_keys, username: user.username - - expect(response.body).not_to eq("") - expect(response.body).to eq(user.all_ssh_keys.join("\n")) - end - - it "should respond with text/plain content type" do - get :get_keys, username: user.username - expect(response.content_type).to eq("text/plain") - end - end - end -end diff --git a/spec/controllers/projects/protected_branches_controller_spec.rb b/spec/controllers/projects/protected_branches_controller_spec.rb deleted file mode 100644 index 596d8d34b7c9a69045afda7cbcee09635c230eed..0000000000000000000000000000000000000000 --- a/spec/controllers/projects/protected_branches_controller_spec.rb +++ /dev/null @@ -1,10 +0,0 @@ -require('spec_helper') - -describe Projects::ProtectedBranchesController do - describe "GET #index" do - let(:project) { create(:project_empty_repo, :public) } - it "redirect empty repo to projects page" do - get(:index, namespace_id: project.namespace.to_param, project_id: project.to_param) - end - end -end diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb deleted file mode 100644 index c254ab7cb6ea518b11c7e80242ead3859e4026e3..0000000000000000000000000000000000000000 --- a/spec/controllers/projects/refs_controller_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'spec_helper' - -describe Projects::RefsController do - let(:project) { create(:project) } - let(:user) { create(:user) } - - before do - sign_in(user) - project.team << [user, :developer] - end - - describe 'GET #logs_tree' do - def default_get(format = :html) - get :logs_tree, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: 'master', - path: 'foo/bar/baz.html', format: format - end - - def xhr_get(format = :html) - xhr :get, :logs_tree, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: 'master', - path: 'foo/bar/baz.html', format: format - end - - it 'never throws MissingTemplate' do - expect { default_get }.not_to raise_error - expect { xhr_get }.not_to raise_error - end - - it 'renders 404 for non-JS requests' do - xhr_get - - expect(response).to be_not_found - end - - it 'renders JS' do - xhr_get(:js) - expect(response).to be_success - end - end -end diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb deleted file mode 100644 index 91856ed0cc0341fbd49a0e7d98be6ae3bd63c385..0000000000000000000000000000000000000000 --- a/spec/controllers/projects/repositories_controller_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require "spec_helper" - -describe Projects::RepositoriesController do - let(:project) { create(:project) } - let(:user) { create(:user) } - - describe "GET archive" do - before do - sign_in(user) - project.team << [user, :developer] - - allow(ArchiveRepositoryService).to receive(:new).and_return(service) - end - - let(:service) { ArchiveRepositoryService.new(project, "master", "zip") } - - it "executes ArchiveRepositoryService" do - expect(ArchiveRepositoryService).to receive(:new).with(project, "master", "zip") - expect(service).to receive(:execute) - - get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip" - end - - context "when the service raises an error" do - - before do - allow(service).to receive(:execute).and_raise("Archive failed") - end - - it "renders Not Found" do - get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip" - - expect(response.status).to eq(404) - end - end - - context "when the service doesn't return a path" do - - before do - allow(service).to receive(:execute).and_return(nil) - end - - it "reloads the page" do - get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip" - - expect(response).to redirect_to(archive_namespace_project_repository_path(project.namespace, project, ref: "master", format: "zip")) - end - end - - context "when the service returns a path" do - - let(:path) { Rails.root.join("spec/fixtures/dk.png").to_s } - - before do - allow(service).to receive(:execute).and_return(path) - end - - it "sends the file" do - get :archive, namespace_id: project.namespace.path, project_id: project.path, ref: "master", format: "zip" - - expect(response.body).to eq(File.binread(path)) - end - end - end -end diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb deleted file mode 100644 index a1b82a32150f7714c239b536e2d923331208292c..0000000000000000000000000000000000000000 --- a/spec/controllers/projects_controller_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require('spec_helper') - -describe ProjectsController do - let(:project) { create(:project) } - let(:public_project) { create(:project, :public) } - let(:user) { create(:user) } - let(:jpg) { fixture_file_upload(Rails.root + 'spec/fixtures/rails_sample.jpg', 'image/jpg') } - let(:txt) { fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') } - - describe "GET show" do - - context "when requested by `go get`" do - render_views - - it "renders the go-import meta tag" do - get :show, "go-get" => "1", namespace_id: "bogus_namespace", id: "bogus_project" - - expect(response.body).to include("name='go-import'") - - content = "localhost/bogus_namespace/bogus_project git http://localhost/bogus_namespace/bogus_project.git" - expect(response.body).to include("content='#{content}'") - end - end - end - - describe "POST #toggle_star" do - it "toggles star if user is signed in" do - sign_in(user) - expect(user.starred?(public_project)).to be_falsey - post(:toggle_star, namespace_id: public_project.namespace.to_param, - id: public_project.to_param) - expect(user.starred?(public_project)).to be_truthy - post(:toggle_star, namespace_id: public_project.namespace.to_param, - id: public_project.to_param) - expect(user.starred?(public_project)).to be_falsey - end - - it "does nothing if user is not signed in" do - post(:toggle_star, namespace_id: project.namespace.to_param, - id: public_project.to_param) - expect(user.starred?(public_project)).to be_falsey - post(:toggle_star, namespace_id: project.namespace.to_param, - id: public_project.to_param) - expect(user.starred?(public_project)).to be_falsey - end - end -end diff --git a/spec/controllers/tree_controller_spec.rb b/spec/controllers/tree_controller_spec.rb deleted file mode 100644 index 7b219819bbce79e4b6f44015c6a7f31b2eb4fb21..0000000000000000000000000000000000000000 --- a/spec/controllers/tree_controller_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'spec_helper' - -describe Projects::TreeController do - let(:project) { create(:project) } - let(:user) { create(:user) } - - before do - sign_in(user) - - project.team << [user, :master] - - allow(project).to receive(:branches).and_return(['master', 'foo/bar/baz']) - allow(project).to receive(:tags).and_return(['v1.0.0', 'v2.0.0']) - controller.instance_variable_set(:@project, project) - end - - describe "GET show" do - # Make sure any errors accessing the tree in our views bubble up to this spec - render_views - - before do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: id) - end - - context "valid branch, no path" do - let(:id) { 'master' } - it { is_expected.to respond_with(:success) } - end - - context "valid branch, valid path" do - let(:id) { 'master/encoding/' } - it { is_expected.to respond_with(:success) } - end - - context "valid branch, invalid path" do - let(:id) { 'master/invalid-path/' } - it { is_expected.to respond_with(:not_found) } - end - - context "invalid branch, valid path" do - let(:id) { 'invalid-branch/encoding/' } - it { is_expected.to respond_with(:not_found) } - end - end - - describe 'GET show with blob path' do - render_views - - before do - get(:show, namespace_id: project.namespace.to_param, - project_id: project.to_param, id: id) - end - - context 'redirect to blob' do - let(:id) { 'master/README.md' } - it 'redirects' do - redirect_url = "/#{project.path_with_namespace}/blob/master/README.md" - expect(subject). - to redirect_to(redirect_url) - end - end - end -end diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb deleted file mode 100644 index 0f9780356b1b0920942b8788475205fa38d200e9..0000000000000000000000000000000000000000 --- a/spec/controllers/uploads_controller_spec.rb +++ /dev/null @@ -1,296 +0,0 @@ -require 'spec_helper' - -describe UploadsController do - let!(:user) { create(:user, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) } - - describe "GET show" do - context "when viewing a user avatar" do - context "when signed in" do - before do - sign_in(user) - end - - context "when the user is blocked" do - before do - user.block - end - - it "redirects to the sign in page" do - get :show, model: "user", mounted_as: "avatar", id: user.id, filename: "image.png" - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when the user isn't blocked" do - it "responds with status 200" do - get :show, model: "user", mounted_as: "avatar", id: user.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - end - - context "when not signed in" do - it "responds with status 200" do - get :show, model: "user", mounted_as: "avatar", id: user.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - end - - context "when viewing a project avatar" do - let!(:project) { create(:project, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) } - - context "when the project is public" do - before do - project.update_attribute(:visibility_level, Project::PUBLIC) - end - - context "when not signed in" do - it "responds with status 200" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - - context "when signed in" do - before do - sign_in(user) - end - - it "responds with status 200" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - end - - context "when the project is private" do - before do - project.update_attribute(:visibility_level, Project::PRIVATE) - end - - context "when not signed in" do - it "redirects to the sign in page" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png" - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when signed in" do - before do - sign_in(user) - end - - context "when the user has access to the project" do - before do - project.team << [user, :master] - end - - context "when the user is blocked" do - before do - user.block - project.team << [user, :master] - end - - it "redirects to the sign in page" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png" - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when the user isn't blocked" do - it "responds with status 200" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - end - - context "when the user doesn't have access to the project" do - it "responds with status 404" do - get :show, model: "project", mounted_as: "avatar", id: project.id, filename: "image.png" - - expect(response.status).to eq(404) - end - end - end - end - end - - context "when viewing a group avatar" do - let!(:group) { create(:group, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) } - let!(:project) { create(:project, namespace: group) } - - context "when the group has public projects" do - before do - project.update_attribute(:visibility_level, Project::PUBLIC) - end - - context "when not signed in" do - it "responds with status 200" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - - context "when signed in" do - before do - sign_in(user) - end - - it "responds with status 200" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - end - - context "when the project doesn't have public projects" do - context "when not signed in" do - it "redirects to the sign in page" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png" - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when signed in" do - before do - sign_in(user) - end - - context "when the user has access to the project" do - before do - project.team << [user, :master] - end - - context "when the user is blocked" do - before do - user.block - project.team << [user, :master] - end - - it "redirects to the sign in page" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png" - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when the user isn't blocked" do - it "responds with status 200" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - end - - context "when the user doesn't have access to the project" do - it "responds with status 404" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png" - - expect(response.status).to eq(404) - end - end - end - end - end - - context "when viewing a note attachment" do - let!(:note) { create(:note, :with_attachment) } - let(:project) { note.project } - - context "when the project is public" do - before do - project.update_attribute(:visibility_level, Project::PUBLIC) - end - - context "when not signed in" do - it "responds with status 200" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - - context "when signed in" do - before do - sign_in(user) - end - - it "responds with status 200" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - end - - context "when the project is private" do - before do - project.update_attribute(:visibility_level, Project::PRIVATE) - end - - context "when not signed in" do - it "redirects to the sign in page" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png" - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when signed in" do - before do - sign_in(user) - end - - context "when the user has access to the project" do - before do - project.team << [user, :master] - end - - context "when the user is blocked" do - before do - user.block - project.team << [user, :master] - end - - it "redirects to the sign in page" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png" - - expect(response).to redirect_to(new_user_session_path) - end - end - - context "when the user isn't blocked" do - it "responds with status 200" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png" - - expect(response.status).to eq(200) - end - end - end - - context "when the user doesn't have access to the project" do - it "responds with status 404" do - get :show, model: "note", mounted_as: "attachment", id: note.id, filename: "image.png" - - expect(response.status).to eq(404) - end - end - end - end - end - end -end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb deleted file mode 100644 index d47a37914df78f8135fe66c08d92d61667e3587e..0000000000000000000000000000000000000000 --- a/spec/controllers/users_controller_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'spec_helper' - -describe UsersController do - let(:user) { create(:user, username: 'user1', name: 'User 1', email: 'user1@gitlab.com') } - - before do - sign_in(user) - end - - describe 'GET #show' do - render_views - - it 'renders the show template' do - get :show, username: user.username - expect(response.status).to eq(200) - expect(response).to render_template('show') - end - end - - describe 'GET #calendar' do - it 'renders calendar' do - get :calendar, username: user.username - expect(response).to render_template('calendar') - end - end - - describe 'GET #calendar_activities' do - let!(:project) { create(:project) } - let!(:user) { create(:user) } - - before do - allow_any_instance_of(User).to receive(:contributed_projects_ids).and_return([project.id]) - project.team << [user, :developer] - end - - it 'assigns @calendar_date' do - get :calendar_activities, username: user.username, date: '2014-07-31' - expect(assigns(:calendar_date)).to eq(Date.parse('2014-07-31')) - end - - it 'renders calendar_activities' do - get :calendar_activities, username: user.username - expect(response).to render_template('calendar_activities') - end - end -end diff --git a/spec/factories.rb b/spec/factories.rb deleted file mode 100644 index a5c335c82bc4a1917d9e37f08247304607a8163c..0000000000000000000000000000000000000000 --- a/spec/factories.rb +++ /dev/null @@ -1,193 +0,0 @@ -include ActionDispatch::TestProcess - -FactoryGirl.define do - sequence :sentence, aliases: [:title, :content] do - Faker::Lorem.sentence - end - - sequence :name do - Faker::Name.name - end - - sequence :file_name do - Faker::Internet.user_name - end - - sequence(:url) { Faker::Internet.uri('http') } - - factory :user, aliases: [:author, :assignee, :owner, :creator] do - email { Faker::Internet.email } - name - sequence(:username) { |n| "#{Faker::Internet.user_name}#{n}" } - password "12345678" - confirmed_at { Time.now } - confirmation_token { nil } - - trait :admin do - admin true - end - - factory :omniauth_user do - ignore do - extern_uid '123456' - provider 'ldapmain' - end - - after(:create) do |user, evaluator| - user.identities << create(:identity, - provider: evaluator.provider, - extern_uid: evaluator.extern_uid - ) - end - end - - factory :admin, traits: [:admin] - end - - factory :group do - sequence(:name) { |n| "group#{n}" } - path { name.downcase.gsub(/\s/, '_') } - type 'Group' - end - - factory :namespace do - sequence(:name) { |n| "namespace#{n}" } - path { name.downcase.gsub(/\s/, '_') } - owner - end - - factory :project_member do - user - project - access_level { ProjectMember::MASTER } - end - - factory :issue do - title - author - project - - trait :closed do - state :closed - end - - trait :reopened do - state :reopened - end - - factory :closed_issue, traits: [:closed] - factory :reopened_issue, traits: [:reopened] - end - - factory :event do - factory :closed_issue_event do - project - action { Event::CLOSED } - target factory: :closed_issue - author factory: :user - end - end - - factory :key do - title - key do - "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" - end - - factory :deploy_key, class: 'DeployKey' do - end - - factory :personal_key do - user - end - - factory :another_key do - key do - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDmTillFzNTrrGgwaCKaSj+QCz81E6jBc/s9av0+3b1Hwfxgkqjl4nAK/OD2NjgyrONDTDfR8cRN4eAAy6nY8GLkOyYBDyuc5nTMqs5z3yVuTwf3koGm/YQQCmo91psZ2BgDFTor8SVEE5Mm1D1k3JDMhDFxzzrOtRYFPci9lskTJaBjpqWZ4E9rDTD2q/QZntCqbC3wE9uSemRQB5f8kik7vD/AD8VQXuzKladrZKkzkONCPWsXDspUitjM8HkQdOf0PsYn1CMUC1xKYbCxkg5TkEosIwGv6CoEArUrdu/4+10LVslq494mAvEItywzrluCLCnwELfW+h/m8UHoVhZ" - end - - factory :another_deploy_key, class: 'DeployKey' do - end - end - end - - factory :email do - user - email do - Faker::Internet.email('alias') - end - - factory :another_email do - email do - Faker::Internet.email('another.alias') - end - end - end - - factory :milestone do - title - project - - trait :closed do - state :closed - end - - factory :closed_milestone, traits: [:closed] - end - - factory :system_hook do - url - end - - factory :project_hook do - url - end - - factory :project_snippet do - project - author - title - content - file_name - end - - factory :personal_snippet do - author - title - content - file_name - end - - factory :snippet do - author - title - content - file_name - end - - factory :protected_branch do - name - project - end - - factory :service do - type "" - title "GitLab CI" - project - end - - factory :service_hook do - url - service - end - - factory :deploy_keys_project do - deploy_key - project - end - - factory :identity do - provider 'ldapmain' - extern_uid 'my-ldap-id' - end -end diff --git a/spec/factories/broadcast_messages.rb b/spec/factories/broadcast_messages.rb deleted file mode 100644 index ea0039d39e67e1d4cf53c213a417a88869a03f27..0000000000000000000000000000000000000000 --- a/spec/factories/broadcast_messages.rb +++ /dev/null @@ -1,27 +0,0 @@ -# == Schema Information -# -# Table name: broadcast_messages -# -# id :integer not null, primary key -# message :text not null -# starts_at :datetime -# ends_at :datetime -# alert_type :integer -# created_at :datetime -# updated_at :datetime -# color :string(255) -# font :string(255) -# - -# Read about factories at https://github.com/thoughtbot/factory_girl - -FactoryGirl.define do - factory :broadcast_message do - message "MyText" - starts_at "2013-11-12 13:43:25" - ends_at "2013-11-12 13:43:25" - alert_type 1 - color "#555555" - font "#BBBBBB" - end -end diff --git a/spec/factories/forked_project_links.rb b/spec/factories/forked_project_links.rb deleted file mode 100644 index 906e4106b320750b1c7d9be608bf4b6fd72be0b1..0000000000000000000000000000000000000000 --- a/spec/factories/forked_project_links.rb +++ /dev/null @@ -1,19 +0,0 @@ -# == Schema Information -# -# Table name: forked_project_links -# -# id :integer not null, primary key -# forked_to_project_id :integer not null -# forked_from_project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - -# Read about factories at https://github.com/thoughtbot/factory_girl - -FactoryGirl.define do - factory :forked_project_link do - association :forked_to_project, factory: :project - association :forked_from_project, factory: :project - end -end diff --git a/spec/factories/group_members.rb b/spec/factories/group_members.rb deleted file mode 100644 index debb86d997f48773b6a323ea08d9228e6f80f883..0000000000000000000000000000000000000000 --- a/spec/factories/group_members.rb +++ /dev/null @@ -1,20 +0,0 @@ -# == Schema Information -# -# Table name: group_members -# -# id :integer not null, primary key -# group_access :integer not null -# group_id :integer not null -# user_id :integer not null -# created_at :datetime -# updated_at :datetime -# notification_level :integer default(3), not null -# - -FactoryGirl.define do - factory :group_member do - access_level { GroupMember::OWNER } - group - user - end -end diff --git a/spec/factories/label_links.rb b/spec/factories/label_links.rb deleted file mode 100644 index bd304b5db6b5214f282e50ff8def59963ce6a212..0000000000000000000000000000000000000000 --- a/spec/factories/label_links.rb +++ /dev/null @@ -1,20 +0,0 @@ -# == Schema Information -# -# Table name: label_links -# -# id :integer not null, primary key -# label_id :integer -# target_id :integer -# target_type :string(255) -# created_at :datetime -# updated_at :datetime -# - -# Read about factories at https://github.com/thoughtbot/factory_girl - -FactoryGirl.define do - factory :label_link do - label - target factory: :issue - end -end diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb deleted file mode 100644 index 6829387c660c86490e08d806fe90f315a8ee29f1..0000000000000000000000000000000000000000 --- a/spec/factories/labels.rb +++ /dev/null @@ -1,21 +0,0 @@ -# == Schema Information -# -# Table name: labels -# -# id :integer not null, primary key -# title :string(255) -# color :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# - -# Read about factories at https://github.com/thoughtbot/factory_girl - -FactoryGirl.define do - factory :label do - title "Bug" - color "#990000" - project - end -end diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb deleted file mode 100644 index 77cd37c22d93c0c85d7cf2fcfacca2d392396667..0000000000000000000000000000000000000000 --- a/spec/factories/merge_requests.rb +++ /dev/null @@ -1,70 +0,0 @@ -# == Schema Information -# -# Table name: merge_requests -# -# id :integer not null, primary key -# target_branch :string(255) not null -# source_branch :string(255) not null -# source_project_id :integer not null -# author_id :integer -# assignee_id :integer -# title :string(255) -# created_at :datetime -# updated_at :datetime -# milestone_id :integer -# state :string(255) -# merge_status :string(255) -# target_project_id :integer not null -# iid :integer -# description :text -# position :integer default(0) -# locked_at :datetime -# - -FactoryGirl.define do - factory :merge_request do - title - author - source_project factory: :project - target_project { source_project } - - # → git log --pretty=oneline feature..master - # 5937ac0a7beb003549fc5fd26fc247adbce4a52e Add submodule from gitlab.com - # 570e7b2abdd848b95f2f578043fc23bd6f6fd24d Change some files - # 6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9 More submodules - # d14d6c0abdd253381df51a723d58691b2ee1ab08 Remove ds_store files - # c1acaa58bbcbc3eafe538cb8274ba387047b69f8 Ignore DS files - # - # See also RepoHelpers.sample_compare - # - source_branch "master" - target_branch "feature" - - merge_status "can_be_merged" - - trait :with_diffs do - end - - trait :conflict do - source_branch "feature_conflict" - target_branch "feature" - end - - trait :closed do - state :closed - end - - trait :reopened do - state :reopened - end - - trait :simple do - source_branch "feature" - target_branch "master" - end - - factory :closed_merge_request, traits: [:closed] - factory :reopened_merge_request, traits: [:reopened] - factory :merge_request_with_diffs, traits: [:with_diffs] - end -end diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb deleted file mode 100644 index f1c33461b55ee93bc294c4be19ed93f0154c49ef..0000000000000000000000000000000000000000 --- a/spec/factories/notes.rb +++ /dev/null @@ -1,65 +0,0 @@ -# == Schema Information -# -# Table name: notes -# -# id :integer not null, primary key -# note :text -# noteable_type :string(255) -# author_id :integer -# created_at :datetime -# updated_at :datetime -# project_id :integer -# attachment :string(255) -# line_code :string(255) -# commit_id :string(255) -# noteable_id :integer -# system :boolean default(FALSE), not null -# st_diff :text -# - -require_relative '../support/repo_helpers' - -FactoryGirl.define do - factory :note do - project - note "Note" - author - - factory :note_on_commit, traits: [:on_commit] - factory :note_on_commit_diff, traits: [:on_commit, :on_diff] - factory :note_on_issue, traits: [:on_issue], aliases: [:votable_note] - factory :note_on_merge_request, traits: [:on_merge_request] - factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff] - factory :note_on_project_snippet, traits: [:on_project_snippet] - - trait :on_commit do - project factory: :project - commit_id RepoHelpers.sample_commit.id - noteable_type "Commit" - end - - trait :on_diff do - line_code "0_184_184" - end - - trait :on_merge_request do - project factory: :project - noteable_id 1 - noteable_type "MergeRequest" - end - - trait :on_issue do - noteable_id 1 - noteable_type "Issue" - end - - trait :on_project_snippet do - noteable_id 1 - noteable_type "Snippet" - end - - trait :with_attachment do - attachment { fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "`/png") } - end - end -end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb deleted file mode 100644 index 0899a7603fcec5b2ffef6c0358e588268298700e..0000000000000000000000000000000000000000 --- a/spec/factories/projects.rb +++ /dev/null @@ -1,95 +0,0 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) -# path :string(255) -# description :text -# created_at :datetime -# updated_at :datetime -# creator_id :integer -# issues_enabled :boolean default(TRUE), not null -# wall_enabled :boolean default(TRUE), not null -# merge_requests_enabled :boolean default(TRUE), not null -# wiki_enabled :boolean default(TRUE), not null -# namespace_id :integer -# issues_tracker :string(255) default("gitlab"), not null -# issues_tracker_id :string(255) -# snippets_enabled :boolean default(TRUE), not null -# last_activity_at :datetime -# import_url :string(255) -# visibility_level :integer default(0), not null -# archived :boolean default(FALSE), not null -# import_status :string(255) -# repository_size :float default(0.0) -# star_count :integer default(0), not null -# import_type :string(255) -# import_source :string(255) -# avatar :string(255) -# - -FactoryGirl.define do - # Project without repository - # - # Project does not have bare repository. - # Use this factory if you dont need repository in tests - factory :empty_project, class: 'Project' do - sequence(:name) { |n| "project#{n}" } - path { name.downcase.gsub(/\s/, '_') } - namespace - creator - snippets_enabled true - - trait :public do - visibility_level Gitlab::VisibilityLevel::PUBLIC - end - - trait :internal do - visibility_level Gitlab::VisibilityLevel::INTERNAL - end - - trait :private do - visibility_level Gitlab::VisibilityLevel::PRIVATE - end - end - - # Project with empty repository - # - # This is a case when you just created a project - # but not pushed any code there yet - factory :project_empty_repo, parent: :empty_project do - after :create do |project| - project.create_repository - end - end - - # Project with test repository - # - # Test repository source can be found at - # https://gitlab.com/gitlab-org/gitlab-test - factory :project, parent: :empty_project do - path { 'gitlabhq' } - - after :create do |project| - TestEnv.copy_repo(project) - end - end - - factory :redmine_project, parent: :project do - after :create do |project| - project.create_redmine_service( - active: true, - properties: { - 'project_url' => 'http://redmine/projects/project_name_in_redmine', - 'issues_url' => "http://redmine/#{project.id}/project_name_in_redmine/:id", - 'new_issue_url' => 'http://redmine/projects/project_name_in_redmine/issues/new' - } - ) - end - after :create do |project| - project.issues_tracker = 'redmine' - project.issues_tracker_id = 'project_name_in_redmine' - end - end -end diff --git a/spec/factories_spec.rb b/spec/factories_spec.rb deleted file mode 100644 index 457859dedaf863931fa5e07ab5e1c029f118c591..0000000000000000000000000000000000000000 --- a/spec/factories_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'spec_helper' - -FactoryGirl.factories.map(&:name).each do |factory_name| - describe "#{factory_name} factory" do - it 'should be valid' do - expect(build(factory_name)).to be_valid - end - end -end diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb deleted file mode 100644 index 25862614d2849e734a96ee8ef00e376fbe436763..0000000000000000000000000000000000000000 --- a/spec/features/admin/admin_hooks_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'spec_helper' - -describe "Admin::Hooks", feature: true do - before do - @project = create(:project) - login_as :admin - - @system_hook = create(:system_hook) - - end - - describe "GET /admin/hooks" do - it "should be ok" do - visit admin_root_path - within ".sidebar-wrapper" do - click_on "Hooks" - end - expect(current_path).to eq(admin_hooks_path) - end - - it "should have hooks list" do - visit admin_hooks_path - expect(page).to have_content(@system_hook.url) - end - end - - describe "New Hook" do - before do - @url = Faker::Internet.uri("http") - visit admin_hooks_path - fill_in "hook_url", with: @url - expect { click_button "Add System Hook" }.to change(SystemHook, :count).by(1) - end - - it "should open new hook popup" do - expect(current_path).to eq(admin_hooks_path) - expect(page).to have_content(@url) - end - end - - describe "Test" do - before do - WebMock.stub_request(:post, @system_hook.url) - visit admin_hooks_path - click_link "Test Hook" - end - - it { expect(current_path).to eq(admin_hooks_path) } - end - -end diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb deleted file mode 100644 index 101d955d693c74d1ee29497fa0df828b03c37560..0000000000000000000000000000000000000000 --- a/spec/features/admin/admin_projects_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -describe "Admin::Projects", feature: true do - before do - @project = create(:project) - login_as :admin - end - - describe "GET /admin/projects" do - before do - visit admin_namespaces_projects_path - end - - it "should be ok" do - expect(current_path).to eq(admin_namespaces_projects_path) - end - - it "should have projects list" do - expect(page).to have_content(@project.name) - end - end - - describe "GET /admin/projects/:id" do - before do - visit admin_namespaces_projects_path - click_link "#{@project.name}" - end - - it "should have project info" do - expect(page).to have_content(@project.path) - expect(page).to have_content(@project.name) - end - end -end diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb deleted file mode 100644 index f97b69713ceca6862bacafa3729342fa99a6fc78..0000000000000000000000000000000000000000 --- a/spec/features/admin/admin_users_spec.rb +++ /dev/null @@ -1,109 +0,0 @@ -require 'spec_helper' - -describe "Admin::Users", feature: true do - before { login_as :admin } - - describe "GET /admin/users" do - before do - visit admin_users_path - end - - it "should be ok" do - expect(current_path).to eq(admin_users_path) - end - - it "should have users list" do - expect(page).to have_content(@user.email) - expect(page).to have_content(@user.name) - end - end - - describe "GET /admin/users/new" do - before do - visit new_admin_user_path - fill_in "user_name", with: "Big Bang" - fill_in "user_username", with: "bang" - fill_in "user_email", with: "bigbang@mail.com" - end - - it "should create new user" do - expect { click_button "Create user" }.to change {User.count}.by(1) - end - - it "should apply defaults to user" do - click_button "Create user" - user = User.find_by(username: 'bang') - expect(user.projects_limit). - to eq(Gitlab.config.gitlab.default_projects_limit) - expect(user.can_create_group). - to eq(Gitlab.config.gitlab.default_can_create_group) - end - - it "should create user with valid data" do - click_button "Create user" - user = User.find_by(username: 'bang') - expect(user.name).to eq('Big Bang') - expect(user.email).to eq('bigbang@mail.com') - end - - it "should call send mail" do - expect(Notify).to receive(:new_user_email) - - click_button "Create user" - end - - it "should send valid email to user with email & password" do - click_button "Create user" - user = User.find_by(username: 'bang') - email = ActionMailer::Base.deliveries.last - expect(email.subject).to have_content('Account was created') - expect(email.text_part.body).to have_content(user.email) - expect(email.text_part.body).to have_content('password') - end - end - - describe "GET /admin/users/:id" do - before do - visit admin_users_path - click_link "#{@user.name}" - end - - it "should have user info" do - expect(page).to have_content(@user.email) - expect(page).to have_content(@user.name) - end - end - - describe "GET /admin/users/:id/edit" do - before do - @simple_user = create(:user) - visit admin_users_path - click_link "edit_user_#{@simple_user.id}" - end - - it "should have user edit page" do - expect(page).to have_content('Name') - expect(page).to have_content('Password') - end - - describe "Update user" do - before do - fill_in "user_name", with: "Big Bang" - fill_in "user_email", with: "bigbang@mail.com" - check "user_admin" - click_button "Save changes" - end - - it "should show page with new data" do - expect(page).to have_content('bigbang@mail.com') - expect(page).to have_content('Big Bang') - end - - it "should change user entry" do - @simple_user.reload - expect(@simple_user.name).to eq('Big Bang') - expect(@simple_user.is_admin?).to be_truthy - end - end - end -end diff --git a/spec/features/admin/security_spec.rb b/spec/features/admin/security_spec.rb deleted file mode 100644 index 175fa9d4647fea1de2cbf57b327d7113efef3cc3..0000000000000000000000000000000000000000 --- a/spec/features/admin/security_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' - -describe "Admin::Projects", feature: true do - describe "GET /admin/projects" do - subject { admin_namespaces_projects_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /admin/users" do - subject { admin_users_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /admin/hooks" do - subject { admin_hooks_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end -end diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb deleted file mode 100644 index b710cb3c72ff33b85d85de20b73bb0d9e954e48f..0000000000000000000000000000000000000000 --- a/spec/features/atom/dashboard_issues_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'spec_helper' - -describe "Dashboard Issues Feed", feature: true do - describe "GET /issues" do - let!(:user) { create(:user) } - let!(:project1) { create(:project) } - let!(:project2) { create(:project) } - let!(:issue1) { create(:issue, author: user, assignee: user, project: project1) } - let!(:issue2) { create(:issue, author: user, assignee: user, project: project2) } - - before do - project1.team << [user, :master] - project2.team << [user, :master] - end - - describe "atom feed" do - it "should render atom feed via private token" do - visit issues_dashboard_path(:atom, private_token: user.private_token) - - expect(response_headers['Content-Type']). - to have_content('application/atom+xml') - expect(body).to have_selector('title', text: "#{user.name} issues") - expect(body).to have_selector('author email', text: issue1.author_email) - expect(body).to have_selector('entry summary', text: issue1.title) - expect(body).to have_selector('author email', text: issue2.author_email) - expect(body).to have_selector('entry summary', text: issue2.title) - end - end - end -end diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb deleted file mode 100644 index ad157d742ff42f4d1fca3453f83daec6eb0cbbbb..0000000000000000000000000000000000000000 --- a/spec/features/atom/dashboard_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'spec_helper' - -describe "Dashboard Feed", feature: true do - describe "GET /" do - let!(:user) { create(:user, name: "Jonh") } - - context "projects atom feed via private token" do - it "should render projects atom feed" do - visit dashboard_path(:atom, private_token: user.private_token) - expect(body).to have_selector('feed title') - end - end - - context 'feed content' do - let(:project) { create(:project) } - let(:issue) { create(:issue, project: project, author: user, description: '') } - let(:note) { create(:note, noteable: issue, author: user, note: 'Bug confirmed', project: project) } - - before do - project.team << [user, :master] - issue_event(issue, user) - note_event(note, user) - visit dashboard_path(:atom, private_token: user.private_token) - end - - it "should have issue opened event" do - expect(body).to have_content("#{user.name} opened issue ##{issue.iid}") - end - - it "should have issue comment event" do - expect(body). - to have_content("#{user.name} commented on issue ##{issue.iid}") - end - end - end - - def issue_event(issue, user) - EventCreateService.new.open_issue(issue, user) - end - - def note_event(note, user) - EventCreateService.new.leave_note(note, user) - end -end diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb deleted file mode 100644 index baa7814e96a017ab5cc74ae3c5a5e12586f14ab3..0000000000000000000000000000000000000000 --- a/spec/features/atom/issues_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'spec_helper' - -describe 'Issues Feed', feature: true do - describe 'GET /issues' do - let!(:user) { create(:user) } - let!(:project) { create(:project) } - let!(:issue) { create(:issue, author: user, project: project) } - - before { project.team << [user, :developer] } - - context 'when authenticated' do - it 'should render atom feed' do - login_with user - visit namespace_project_issues_path(project.namespace, project, :atom) - - expect(response_headers['Content-Type']). - to have_content('application/atom+xml') - expect(body).to have_selector('title', text: "#{project.name} issues") - expect(body).to have_selector('author email', text: issue.author_email) - expect(body).to have_selector('entry summary', text: issue.title) - end - end - - context 'when authenticated via private token' do - it 'should render atom feed' do - visit namespace_project_issues_path(project.namespace, project, :atom, - private_token: user.private_token) - - expect(response_headers['Content-Type']). - to have_content('application/atom+xml') - expect(body).to have_selector('title', text: "#{project.name} issues") - expect(body).to have_selector('author email', text: issue.author_email) - expect(body).to have_selector('entry summary', text: issue.title) - end - end - end -end diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb deleted file mode 100644 index 770ac04c2c57f49b68bb9d93e99d3bb41d253a5d..0000000000000000000000000000000000000000 --- a/spec/features/atom/users_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'spec_helper' - -describe "User Feed", feature: true do - describe "GET /" do - let!(:user) { create(:user) } - - context 'user atom feed via private token' do - it "should render user atom feed" do - visit user_path(user, :atom, private_token: user.private_token) - expect(body).to have_selector('feed title') - end - end - - context 'feed content' do - let(:project) { create(:project) } - let(:issue) do - create(:issue, project: project, - author: user, description: "Houston, we have a bug!\n\n***\n\nI guess.") - end - let(:note) do - create(:note, noteable: issue, author: user, - note: 'Bug confirmed :+1:', project: project) - end - let(:merge_request) do - create(:merge_request, - title: 'Fix bug', author: user, - source_project: project, target_project: project, - description: "Here is the fix: ![an image](image.png)") - end - - before do - project.team << [user, :master] - issue_event(issue, user) - note_event(note, user) - merge_request_event(merge_request, user) - visit user_path(user, :atom, private_token: user.private_token) - end - - it 'should have issue opened event' do - expect(body).to have_content("#{safe_name} opened issue ##{issue.iid}") - end - - it 'should have issue comment event' do - expect(body). - to have_content("#{safe_name} commented on issue ##{issue.iid}") - end - - it 'should have XHTML summaries in issue descriptions' do - expect(body).to match /we have a bug!<\/p>\n\n
    \n\n

    I guess/ - end - - it 'should have XHTML summaries in notes' do - expect(body).to match /Bug confirmed ]*\/>/ - end - - it 'should have XHTML summaries in merge request descriptions' do - expect(body).to match /Here is the fix: ]*\/>/ - end - end - end - - def issue_event(issue, user) - EventCreateService.new.open_issue(issue, user) - end - - def note_event(note, user) - EventCreateService.new.leave_note(note, user) - end - - def merge_request_event(request, user) - EventCreateService.new.open_mr(request, user) - end - - def safe_name - html_escape(user.name) - end -end diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb deleted file mode 100644 index fca1a06eb88d3d0ec2dd397a5e95cf9aec723ef6..0000000000000000000000000000000000000000 --- a/spec/features/gitlab_flavored_markdown_spec.rb +++ /dev/null @@ -1,129 +0,0 @@ -require 'spec_helper' - -describe "GitLab Flavored Markdown", feature: true do - let(:project) { create(:project) } - let(:issue) { create(:issue, project: project) } - let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let(:fred) do - u = create(:user, name: "fred") - project.team << [u, :master] - u - end - - before do - Commit.any_instance.stub(title: "fix ##{issue.iid}\n\nask @#{fred.username} for details") - end - - let(:commit) { project.repository.commit } - - before do - login_as :user - project.team << [@user, :developer] - end - - describe "for commits" do - it "should render title in commits#index" do - visit namespace_project_commits_path(project.namespace, project, 'master', limit: 1) - - expect(page).to have_link("##{issue.iid}") - end - - it "should render title in commits#show" do - visit namespace_project_commit_path(project.namespace, project, commit) - - expect(page).to have_link("##{issue.iid}") - end - - it "should render description in commits#show" do - visit namespace_project_commit_path(project.namespace, project, commit) - - expect(page).to have_link("@#{fred.username}") - end - - it "should render title in repositories#branches" do - visit namespace_project_branches_path(project.namespace, project) - - expect(page).to have_link("##{issue.iid}") - end - end - - describe "for issues" do - before do - @other_issue = create(:issue, - author: @user, - assignee: @user, - project: project) - @issue = create(:issue, - author: @user, - assignee: @user, - project: project, - title: "fix ##{@other_issue.iid}", - description: "ask @#{fred.username} for details") - end - - it "should render subject in issues#index" do - visit namespace_project_issues_path(project.namespace, project) - - expect(page).to have_link("##{@other_issue.iid}") - end - - it "should render subject in issues#show" do - visit namespace_project_issue_path(project.namespace, project, @issue) - - expect(page).to have_link("##{@other_issue.iid}") - end - - it "should render details in issues#show" do - visit namespace_project_issue_path(project.namespace, project, @issue) - - expect(page).to have_link("@#{fred.username}") - end - end - - - describe "for merge requests" do - before do - @merge_request = create(:merge_request, source_project: project, target_project: project, title: "fix ##{issue.iid}") - end - - it "should render title in merge_requests#index" do - visit namespace_project_merge_requests_path(project.namespace, project) - - expect(page).to have_link("##{issue.iid}") - end - - it "should render title in merge_requests#show" do - visit namespace_project_merge_request_path(project.namespace, project, @merge_request) - - expect(page).to have_link("##{issue.iid}") - end - end - - - describe "for milestones" do - before do - @milestone = create(:milestone, - project: project, - title: "fix ##{issue.iid}", - description: "ask @#{fred.username} for details") - end - - it "should render title in milestones#index" do - visit namespace_project_milestones_path(project.namespace, project) - - expect(page).to have_link("##{issue.iid}") - end - - it "should render title in milestones#show" do - visit namespace_project_milestone_path(project.namespace, project, @milestone) - - expect(page).to have_link("##{issue.iid}") - end - - it "should render description in milestones#show" do - visit namespace_project_milestone_path(project.namespace, project, @milestone) - - expect(page).to have_link("@#{fred.username}") - end - end -end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb deleted file mode 100644 index e5f33d5a25acba8971b86f6cdbe7240875a43898..0000000000000000000000000000000000000000 --- a/spec/features/issues_spec.rb +++ /dev/null @@ -1,320 +0,0 @@ -require 'spec_helper' - -describe 'Issues', feature: true do - include SortingHelper - - let(:project) { create(:project) } - - before do - login_as :user - user2 = create(:user) - - project.team << [[@user, user2], :developer] - end - - describe 'Edit issue' do - let!(:issue) do - create(:issue, - author: @user, - assignee: @user, - project: project) - end - - before do - visit namespace_project_issues_path(project.namespace, project) - click_link "Edit" - end - - it 'should open new issue popup' do - expect(page).to have_content("Issue ##{issue.iid}") - end - - describe 'fill in' do - before do - fill_in 'issue_title', with: 'bug 345' - fill_in 'issue_description', with: 'bug description' - end - - it 'does not change issue count' do - expect { - click_button 'Save changes' - }.to_not change { Issue.count } - end - - it 'should update issue fields' do - click_button 'Save changes' - - expect(page).to have_content @user.name - expect(page).to have_content 'bug 345' - expect(page).to have_content project.name - end - end - - end - - describe 'Editing issue assignee' do - let!(:issue) do - create(:issue, - author: @user, - assignee: @user, - project: project) - end - - it 'allows user to select unasigned', js: true do - visit edit_namespace_project_issue_path(project.namespace, project, issue) - - expect(page).to have_content "Assign to #{@user.name}" - - first('#s2id_issue_assignee_id').click - sleep 2 # wait for ajax stuff to complete - first('.user-result').click - - click_button 'Save changes' - - expect(page).to have_content 'Assignee: none' - expect(issue.reload.assignee).to be_nil - end - end - - describe 'Filter issue' do - before do - ['foobar', 'barbaz', 'gitlab'].each do |title| - create(:issue, - author: @user, - assignee: @user, - project: project, - title: title) - end - - @issue = Issue.find_by(title: 'foobar') - @issue.milestone = create(:milestone, project: project) - @issue.assignee = nil - @issue.save - end - - let(:issue) { @issue } - - it 'should allow filtering by issues with no specified milestone' do - visit namespace_project_issues_path(project.namespace, project, milestone_id: IssuableFinder::NONE) - - expect(page).not_to have_content 'foobar' - expect(page).to have_content 'barbaz' - expect(page).to have_content 'gitlab' - end - - it 'should allow filtering by a specified milestone' do - visit namespace_project_issues_path(project.namespace, project, milestone_id: issue.milestone.id) - - expect(page).to have_content 'foobar' - expect(page).not_to have_content 'barbaz' - expect(page).not_to have_content 'gitlab' - end - - it 'should allow filtering by issues with no specified assignee' do - visit namespace_project_issues_path(project.namespace, project, assignee_id: IssuableFinder::NONE) - - expect(page).to have_content 'foobar' - expect(page).not_to have_content 'barbaz' - expect(page).not_to have_content 'gitlab' - end - - it 'should allow filtering by a specified assignee' do - visit namespace_project_issues_path(project.namespace, project, assignee_id: @user.id) - - expect(page).not_to have_content 'foobar' - expect(page).to have_content 'barbaz' - expect(page).to have_content 'gitlab' - end - end - - describe 'filter issue' do - titles = ['foo','bar','baz'] - titles.each_with_index do |title, index| - let!(title.to_sym) do - create(:issue, title: title, - project: project, - created_at: Time.now - (index * 60)) - end - end - let(:newer_due_milestone) { create(:milestone, due_date: '2013-12-11') } - let(:later_due_milestone) { create(:milestone, due_date: '2013-12-12') } - - it 'sorts by newest' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_recently_created) - - expect(first_issue).to include('foo') - expect(last_issue).to include('baz') - end - - it 'sorts by oldest' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_oldest_created) - - expect(first_issue).to include('baz') - expect(last_issue).to include('foo') - end - - it 'sorts by most recently updated' do - baz.updated_at = Time.now + 100 - baz.save - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_recently_updated) - - expect(first_issue).to include('baz') - end - - it 'sorts by least recently updated' do - baz.updated_at = Time.now - 100 - baz.save - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_oldest_updated) - - expect(first_issue).to include('baz') - end - - describe 'sorting by milestone' do - before :each do - foo.milestone = newer_due_milestone - foo.save - bar.milestone = later_due_milestone - bar.save - end - - it 'sorts by recently due milestone' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_milestone_soon) - - expect(first_issue).to include('foo') - end - - it 'sorts by least recently due milestone' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_milestone_later) - - expect(first_issue).to include('bar') - end - end - - describe 'combine filter and sort' do - let(:user2) { create(:user) } - - before :each do - foo.assignee = user2 - foo.save - bar.assignee = user2 - bar.save - end - - it 'sorts with a filter applied' do - visit namespace_project_issues_path(project.namespace, project, - sort: sort_value_oldest_created, - assignee_id: user2.id) - - expect(first_issue).to include('bar') - expect(last_issue).to include('foo') - expect(page).not_to have_content 'baz' - end - end - end - - describe 'update assignee from issue#show' do - let(:issue) { create(:issue, project: project, author: @user) } - - context 'by autorized user' do - - it 'with dropdown menu' do - visit namespace_project_issue_path(project.namespace, project, issue) - - find('.edit-issue.inline-update #issue_assignee_id'). - set project.team.members.first.id - click_button 'Update Issue' - - expect(page).to have_content 'Assignee:' - has_select?('issue_assignee_id', - selected: project.team.members.first.name) - end - end - - context 'by unauthorized user' do - - let(:guest) { create(:user) } - - before :each do - project.team << [[guest], :guest] - issue.assignee = @user - issue.save - end - - it 'shows assignee text', js: true do - logout - login_with guest - - visit namespace_project_issue_path(project.namespace, project, issue) - expect(page).to have_content issue.assignee.name - end - end - end - - describe 'update milestone from issue#show' do - let!(:issue) { create(:issue, project: project, author: @user) } - let!(:milestone) { create(:milestone, project: project) } - - context 'by authorized user' do - - it 'with dropdown menu' do - visit namespace_project_issue_path(project.namespace, project, issue) - - find('.edit-issue.inline-update'). - select(milestone.title, from: 'issue_milestone_id') - click_button 'Update Issue' - - expect(page).to have_content "Milestone changed to #{milestone.title}" - expect(page).to have_content "Milestone: #{milestone.title}" - has_select?('issue_assignee_id', selected: milestone.title) - end - end - - context 'by unauthorized user' do - let(:guest) { create(:user) } - - before :each do - project.team << [guest, :guest] - issue.milestone = milestone - issue.save - end - - it 'shows milestone text', js: true do - logout - login_with guest - - visit namespace_project_issue_path(project.namespace, project, issue) - expect(page).to have_content milestone.title - end - end - - describe 'removing assignee' do - let(:user2) { create(:user) } - - before :each do - issue.assignee = user2 - issue.save - end - - it 'allows user to remove assignee', :js => true do - visit namespace_project_issue_path(project.namespace, project, issue) - expect(page).to have_content "Assignee: #{user2.name}" - - first('#s2id_issue_assignee_id').click - sleep 2 # wait for ajax stuff to complete - first('.user-result').click - - expect(page).to have_content 'Assignee: none' - sleep 2 # wait for ajax stuff to complete - expect(issue.reload.assignee).to be_nil - end - end - end - - def first_issue - all('ul.issues-list li').first.text - end - - def last_issue - all('ul.issues-list li').last.text - end -end diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb deleted file mode 100644 index c47368b1fdaa13ff39c3e1740a443be7a12a11ec..0000000000000000000000000000000000000000 --- a/spec/features/notes_on_merge_requests_spec.rb +++ /dev/null @@ -1,230 +0,0 @@ -require 'spec_helper' - -describe 'Comments' do - include RepoHelpers - - describe 'On a merge request', js: true, feature: true do - let!(:merge_request) { create(:merge_request) } - let!(:project) { merge_request.source_project } - let!(:note) do - create(:note_on_merge_request, :with_attachment, project: project) - end - - before do - login_as :admin - visit namespace_project_merge_request_path(project.namespace, project, merge_request) - end - - subject { page } - - describe 'the note form' do - it 'should be valid' do - is_expected.to have_css('.js-main-target-form', visible: true, count: 1) - expect(find('.js-main-target-form input[type=submit]').value). - to eq('Add Comment') - within('.js-main-target-form') do - expect(page).not_to have_link('Cancel') - end - end - - describe 'with text' do - before do - within('.js-main-target-form') do - fill_in 'note[note]', with: 'This is awesome' - end - end - - it 'should have enable submit button and preview button' do - within('.js-main-target-form') do - expect(page).not_to have_css('.js-comment-button[disabled]') - expect(page).to have_css('.js-md-preview-button', visible: true) - end - end - end - end - - describe 'when posting a note' do - before do - within('.js-main-target-form') do - fill_in 'note[note]', with: 'This is awsome!' - find('.js-md-preview-button').click - click_button 'Add Comment' - end - end - - it 'should be added and form reset' do - is_expected.to have_content('This is awsome!') - within('.js-main-target-form') do - expect(page).to have_no_field('note[note]', with: 'This is awesome!') - expect(page).to have_css('.js-md-preview', visible: :hidden) - end - within('.js-main-target-form') do - is_expected.to have_css('.js-note-text', visible: true) - end - end - end - - describe 'when editing a note', js: true do - it 'should contain the hidden edit form' do - within("#note_#{note.id}") do - is_expected.to have_css('.note-edit-form', visible: false) - end - end - - describe 'editing the note' do - before do - find('.note').hover - find(".js-note-edit").click - end - - it 'should show the note edit form and hide the note body' do - within("#note_#{note.id}") do - expect(find('.current-note-edit-form', visible: true)).to be_visible - expect(find('.note-edit-form', visible: true)).to be_visible - expect(find(:css, '.note-body > .note-text', visible: false)).not_to be_visible - end - end - - # TODO: fix after 7.7 release - #it "should reset the edit note form textarea with the original content of the note if cancelled" do - #within(".current-note-edit-form") do - #fill_in "note[note]", with: "Some new content" - #find(".btn-cancel").click - #find(".js-note-text", visible: false).text.should == note.note - #end - #end - - it 'appends the edited at time to the note' do - within('.current-note-edit-form') do - fill_in 'note[note]', with: 'Some new content' - find('.btn-save').click - end - - within("#note_#{note.id}") do - is_expected.to have_css('.note_edited_ago') - expect(find('.note_edited_ago').text). - to match(/less than a minute ago/) - end - end - end - - describe 'deleting an attachment' do - before do - find('.note').hover - find('.js-note-edit').click - end - - it 'shows the delete link' do - within('.note-attachment') do - is_expected.to have_css('.js-note-attachment-delete') - end - end - - it 'removes the attachment div and resets the edit form' do - find('.js-note-attachment-delete').click - is_expected.not_to have_css('.note-attachment') - expect(find('.current-note-edit-form', visible: false)). - not_to be_visible - end - end - end - end - - describe 'On a merge request diff', js: true, feature: true do - let(:merge_request) { create(:merge_request) } - let(:project) { merge_request.source_project } - - before do - login_as :admin - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) - end - - subject { page } - - describe 'when adding a note' do - before do - click_diff_line - end - - describe 'the notes holder' do - it { is_expected.to have_css('.js-temp-notes-holder') } - - it 'has .new_note css class' do - within('.js-temp-notes-holder') do - expect(subject).to have_css('.new_note') - end - end - end - - describe 'the note form' do - it "shouldn't add a second form for same row" do - click_diff_line - - is_expected. - to have_css("tr[id='#{line_code}'] + .js-temp-notes-holder form", - count: 1) - end - - it 'should be removed when canceled' do - within(".diff-file form[rel$='#{line_code}']") do - find('.js-close-discussion-note-form').trigger('click') - end - - is_expected.to have_no_css('.js-temp-notes-holder') - end - end - end - - describe 'with muliple note forms' do - before do - click_diff_line - click_diff_line(line_code_2) - end - - it { is_expected.to have_css('.js-temp-notes-holder', count: 2) } - - describe 'previewing them separately' do - before do - # add two separate texts and trigger previews on both - within("tr[id='#{line_code}'] + .js-temp-notes-holder") do - fill_in 'note[note]', with: 'One comment on line 7' - find('.js-md-preview-button').click - end - within("tr[id='#{line_code_2}'] + .js-temp-notes-holder") do - fill_in 'note[note]', with: 'Another comment on line 10' - find('.js-md-preview-button').click - end - end - end - - describe 'posting a note' do - before do - within("tr[id='#{line_code_2}'] + .js-temp-notes-holder") do - fill_in 'note[note]', with: 'Another comment on line 10' - click_button('Add Comment') - end - end - - it 'should be added as discussion' do - is_expected.to have_content('Another comment on line 10') - is_expected.to have_css('.notes_holder') - is_expected.to have_css('.notes_holder .note', count: 1) - is_expected.to have_button('Reply') - end - end - end - end - - def line_code - sample_compare.changes.first[:line_code] - end - - def line_code_2 - sample_compare.changes.last[:line_code] - end - - def click_diff_line(data = nil) - data ||= line_code - find("button[data-line-code=\"#{data}\"]").click - end -end diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb deleted file mode 100644 index 3d36a3c02d043cc989cfc682273d2c5c6b989e2d..0000000000000000000000000000000000000000 --- a/spec/features/profile_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'spec_helper' - -describe 'Profile account page', feature: true do - let(:user) { create(:user) } - - before do - login_as :user - end - - describe 'when signup is enabled' do - before do - ApplicationSetting.any_instance.stub(signup_enabled?: true) - visit profile_account_path - end - - it { expect(page).to have_content('Remove account') } - - it 'should delete the account' do - expect { click_link 'Delete account' }.to change { User.count }.by(-1) - expect(current_path).to eq(new_user_session_path) - end - end - - describe 'when signup is disabled' do - before do - ApplicationSetting.any_instance.stub(signup_enabled?: false) - visit profile_account_path - end - - it 'should not have option to remove account' do - expect(page).not_to have_content('Remove account') - expect(current_path).to eq(profile_account_path) - end - end -end diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb deleted file mode 100644 index cae11be7cdd32b06c30738d919ae1e077e5ba681..0000000000000000000000000000000000000000 --- a/spec/features/projects_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'spec_helper' - -describe "Projects", feature: true, js: true do - before { login_as :user } - - describe "DELETE /projects/:id" do - before do - @project = create(:project, namespace: @user.namespace) - @project.team << [@user, :master] - visit edit_namespace_project_path(@project.namespace, @project) - end - - it "should remove project" do - expect { remove_project }.to change {Project.count}.by(-1) - end - - it 'should delete the project from disk' do - expect(GitlabShellWorker).to( - receive(:perform_async).with(:remove_repository, - /#{@project.path_with_namespace}/) - ).twice - - remove_project - end - end - - def remove_project - click_link "Remove project" - fill_in 'confirm_name_input', with: @project.path - click_button 'Confirm' - end -end diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb deleted file mode 100644 index 73987739a7a5ea67d08b995bc53d5820fdbabf75..0000000000000000000000000000000000000000 --- a/spec/features/search_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'spec_helper' - -describe "Search", feature: true do - before do - login_as :user - @project = create(:project, namespace: @user.namespace) - @project.team << [@user, :reporter] - visit search_path - - within '.search-holder' do - fill_in "search", with: @project.name[0..3] - click_button "Search" - end - end - - it "should show project in search results" do - expect(page).to have_content @project.name - end -end - diff --git a/spec/features/security/dashboard_access_spec.rb b/spec/features/security/dashboard_access_spec.rb deleted file mode 100644 index 67238e3ab76029f1994bb9ddffeed26bb65fc291..0000000000000000000000000000000000000000 --- a/spec/features/security/dashboard_access_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'spec_helper' - -describe "Dashboard access", feature: true do - describe "GET /dashboard" do - subject { dashboard_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /dashboard/issues" do - subject { issues_dashboard_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /dashboard/merge_requests" do - subject { merge_requests_dashboard_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /dashboard/projects/starred" do - subject { starred_dashboard_projects_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /help" do - subject { help_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /projects/new" do - it { expect(new_project_path).to be_allowed_for :admin } - it { expect(new_project_path).to be_allowed_for :user } - it { expect(new_project_path).to be_denied_for :visitor } - end - - describe "GET /groups/new" do - it { expect(new_group_path).to be_allowed_for :admin } - it { expect(new_group_path).to be_allowed_for :user } - it { expect(new_group_path).to be_denied_for :visitor } - end - - describe "GET /profile/groups" do - subject { dashboard_groups_path } - - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end -end diff --git a/spec/features/security/group/group_access_spec.rb b/spec/features/security/group/group_access_spec.rb deleted file mode 100644 index 63793149459ab2b4a01a164628f443ced51d0f06..0000000000000000000000000000000000000000 --- a/spec/features/security/group/group_access_spec.rb +++ /dev/null @@ -1,98 +0,0 @@ -require 'spec_helper' - -describe "Group access", feature: true do - describe "GET /projects/new" do - it { expect(new_group_path).to be_allowed_for :admin } - it { expect(new_group_path).to be_allowed_for :user } - it { expect(new_group_path).to be_denied_for :visitor } - end - - describe "Group" do - let(:group) { create(:group) } - - let(:owner) { create(:owner) } - let(:master) { create(:user) } - let(:reporter) { create(:user) } - let(:guest) { create(:user) } - let(:nonmember) { create(:user) } - - before do - group.add_user(owner, Gitlab::Access::OWNER) - group.add_user(master, Gitlab::Access::MASTER) - group.add_user(reporter, Gitlab::Access::REPORTER) - group.add_user(guest, Gitlab::Access::GUEST) - end - - describe "GET /groups/:path" do - subject { group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/issues" do - subject { issues_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/merge_requests" do - subject { merge_requests_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/group_members" do - subject { group_group_members_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/edit" do - subject { edit_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_denied_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/projects" do - subject { projects_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_denied_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - end -end diff --git a/spec/features/security/group/internal_group_access_spec.rb b/spec/features/security/group/internal_group_access_spec.rb deleted file mode 100644 index d17a7412e43874c3ea826e3520958d20f154b7b7..0000000000000000000000000000000000000000 --- a/spec/features/security/group/internal_group_access_spec.rb +++ /dev/null @@ -1,82 +0,0 @@ -require 'spec_helper' - -describe "Group with internal project access", feature: true do - describe "Group" do - let(:group) { create(:group) } - - let(:owner) { create(:owner) } - let(:master) { create(:user) } - let(:reporter) { create(:user) } - let(:guest) { create(:user) } - let(:nonmember) { create(:user) } - - before do - group.add_user(owner, Gitlab::Access::OWNER) - group.add_user(master, Gitlab::Access::MASTER) - group.add_user(reporter, Gitlab::Access::REPORTER) - group.add_user(guest, Gitlab::Access::GUEST) - - create(:project, :internal, group: group) - end - - describe "GET /groups/:path" do - subject { group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/issues" do - subject { issues_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/merge_requests" do - subject { merge_requests_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/group_members" do - subject { group_group_members_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /groups/:path/edit" do - subject { edit_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_denied_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - end -end diff --git a/spec/features/security/group/mixed_group_access_spec.rb b/spec/features/security/group/mixed_group_access_spec.rb deleted file mode 100644 index b3db7b5dea4404337e9eba20df6d6a85f9395efd..0000000000000000000000000000000000000000 --- a/spec/features/security/group/mixed_group_access_spec.rb +++ /dev/null @@ -1,83 +0,0 @@ -require 'spec_helper' - -describe "Group access", feature: true do - describe "Group" do - let(:group) { create(:group) } - - let(:owner) { create(:owner) } - let(:master) { create(:user) } - let(:reporter) { create(:user) } - let(:guest) { create(:user) } - let(:nonmember) { create(:user) } - - before do - group.add_user(owner, Gitlab::Access::OWNER) - group.add_user(master, Gitlab::Access::MASTER) - group.add_user(reporter, Gitlab::Access::REPORTER) - group.add_user(guest, Gitlab::Access::GUEST) - - create(:project, :internal, path: "internal_project", group: group) - create(:project, :public, path: "public_project", group: group) - end - - describe "GET /groups/:path" do - subject { group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /groups/:path/issues" do - subject { issues_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /groups/:path/merge_requests" do - subject { merge_requests_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /groups/:path/group_members" do - subject { group_group_members_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /groups/:path/edit" do - subject { edit_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_denied_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - end -end diff --git a/spec/features/security/group/public_group_access_spec.rb b/spec/features/security/group/public_group_access_spec.rb deleted file mode 100644 index c16f0c0d1e1d004c7276c426a9f49b01d2b381fb..0000000000000000000000000000000000000000 --- a/spec/features/security/group/public_group_access_spec.rb +++ /dev/null @@ -1,82 +0,0 @@ -require 'spec_helper' - -describe "Group with public project access", feature: true do - describe "Group" do - let(:group) { create(:group) } - - let(:owner) { create(:owner) } - let(:master) { create(:user) } - let(:reporter) { create(:user) } - let(:guest) { create(:user) } - let(:nonmember) { create(:user) } - - before do - group.add_user(owner, Gitlab::Access::OWNER) - group.add_user(master, Gitlab::Access::MASTER) - group.add_user(reporter, Gitlab::Access::REPORTER) - group.add_user(guest, Gitlab::Access::GUEST) - - create(:project, :public, group: group) - end - - describe "GET /groups/:path" do - subject { group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /groups/:path/issues" do - subject { issues_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /groups/:path/merge_requests" do - subject { merge_requests_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /groups/:path/group_members" do - subject { group_group_members_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /groups/:path/edit" do - subject { edit_group_path(group) } - - it { is_expected.to be_allowed_for owner } - it { is_expected.to be_denied_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - end -end diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb deleted file mode 100644 index 2512a9c0e3d414a36f920ab780b22ebaa63a091d..0000000000000000000000000000000000000000 --- a/spec/features/security/profile_access_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'spec_helper' - -describe "Profile access", feature: true do - before do - @u1 = create(:user) - end - - describe "GET /login" do - it { expect(new_user_session_path).not_to be_404_for :visitor } - end - - describe "GET /profile/keys" do - subject { profile_keys_path } - - it { is_expected.to be_allowed_for @u1 } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /profile" do - subject { profile_path } - - it { is_expected.to be_allowed_for @u1 } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /profile/account" do - subject { profile_account_path } - - it { is_expected.to be_allowed_for @u1 } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /profile/design" do - subject { design_profile_path } - - it { is_expected.to be_allowed_for @u1 } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /profile/history" do - subject { history_profile_path } - - it { is_expected.to be_allowed_for @u1 } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /profile/notifications" do - subject { profile_notifications_path } - - it { is_expected.to be_allowed_for @u1 } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end -end diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb deleted file mode 100644 index 8d1bfd2522337eef7eff0a7f7baf9b88755e8ff0..0000000000000000000000000000000000000000 --- a/spec/features/security/project/internal_access_spec.rb +++ /dev/null @@ -1,227 +0,0 @@ -require 'spec_helper' - -describe "Internal Project Access", feature: true do - let(:project) { create(:project, :internal) } - - let(:master) { create(:user) } - let(:guest) { create(:user) } - let(:reporter) { create(:user) } - - before do - # full access - project.team << [master, :master] - - # readonly - project.team << [reporter, :reporter] - end - - describe "Project should be internal" do - subject { project } - - describe '#internal?' do - subject { super().internal? } - it { is_expected.to be_truthy } - end - end - - describe "GET /:project_path" do - subject { namespace_project_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/tree/master" do - subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/commits/master" do - subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/commit/:sha" do - subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/compare" do - subject { namespace_project_compare_index_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/project_members" do - subject { namespace_project_project_members_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/blob" do - before do - commit = project.repository.commit - path = '.gitignore' - @blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path)) - end - - it { expect(@blob_path).to be_allowed_for master } - it { expect(@blob_path).to be_allowed_for reporter } - it { expect(@blob_path).to be_allowed_for :admin } - it { expect(@blob_path).to be_allowed_for guest } - it { expect(@blob_path).to be_allowed_for :user } - it { expect(@blob_path).to be_denied_for :visitor } - end - - describe "GET /:project_path/edit" do - subject { edit_namespace_project_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/deploy_keys" do - subject { namespace_project_deploy_keys_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/issues" do - subject { namespace_project_issues_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/snippets/new" do - subject { new_namespace_project_snippet_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/merge_requests" do - subject { namespace_project_merge_requests_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/merge_requests/new" do - subject { new_namespace_project_merge_request_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/branches" do - subject { namespace_project_branches_path(project.namespace, project) } - - before do - # Speed increase - allow_any_instance_of(Project).to receive(:branches).and_return([]) - end - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/tags" do - subject { namespace_project_tags_path(project.namespace, project) } - - before do - # Speed increase - allow_any_instance_of(Project).to receive(:tags).and_return([]) - end - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/hooks" do - subject { namespace_project_hooks_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end -end diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb deleted file mode 100644 index 9021ff331868772b533d7485235fd786e1d3ecb7..0000000000000000000000000000000000000000 --- a/spec/features/security/project/private_access_spec.rb +++ /dev/null @@ -1,205 +0,0 @@ -require 'spec_helper' - -describe "Private Project Access", feature: true do - let(:project) { create(:project) } - - let(:master) { create(:user) } - let(:guest) { create(:user) } - let(:reporter) { create(:user) } - - before do - # full access - project.team << [master, :master] - - # readonly - project.team << [reporter, :reporter] - end - - describe "Project should be private" do - subject { project } - - describe '#private?' do - subject { super().private? } - it { is_expected.to be_truthy } - end - end - - describe "GET /:project_path" do - subject { namespace_project_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/tree/master" do - subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/commits/master" do - subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/commit/:sha" do - subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/compare" do - subject { namespace_project_compare_index_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/project_members" do - subject { namespace_project_project_members_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/blob" do - before do - commit = project.repository.commit - path = '.gitignore' - @blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path)) - end - - it { expect(@blob_path).to be_allowed_for master } - it { expect(@blob_path).to be_allowed_for reporter } - it { expect(@blob_path).to be_allowed_for :admin } - it { expect(@blob_path).to be_denied_for guest } - it { expect(@blob_path).to be_denied_for :user } - it { expect(@blob_path).to be_denied_for :visitor } - end - - describe "GET /:project_path/edit" do - subject { edit_namespace_project_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/deploy_keys" do - subject { namespace_project_deploy_keys_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/issues" do - subject { namespace_project_issues_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/merge_requests" do - subject { namespace_project_merge_requests_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/branches" do - subject { namespace_project_branches_path(project.namespace, project) } - - before do - # Speed increase - allow_any_instance_of(Project).to receive(:branches).and_return([]) - end - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/tags" do - subject { namespace_project_tags_path(project.namespace, project) } - - before do - # Speed increase - allow_any_instance_of(Project).to receive(:tags).and_return([]) - end - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/hooks" do - subject { namespace_project_hooks_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end -end diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb deleted file mode 100644 index 6ec190ed777e81a323a5c966777eecae8ad991b1..0000000000000000000000000000000000000000 --- a/spec/features/security/project/public_access_spec.rb +++ /dev/null @@ -1,232 +0,0 @@ -require 'spec_helper' - -describe "Public Project Access", feature: true do - let(:project) { create(:project) } - - let(:master) { create(:user) } - let(:guest) { create(:user) } - let(:reporter) { create(:user) } - - before do - # public project - project.visibility_level = Gitlab::VisibilityLevel::PUBLIC - project.save! - - # full access - project.team << [master, :master] - - # readonly - project.team << [reporter, :reporter] - - end - - describe "Project should be public" do - subject { project } - - describe '#public?' do - subject { super().public? } - it { is_expected.to be_truthy } - end - end - - describe "GET /:project_path" do - subject { namespace_project_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/tree/master" do - subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/commits/master" do - subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/commit/:sha" do - subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/compare" do - subject { namespace_project_compare_index_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/project_members" do - subject { namespace_project_project_members_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/blob" do - before do - commit = project.repository.commit - path = '.gitignore' - @blob_path = namespace_project_blob_path(project.namespace, project, File.join(commit.id, path)) - end - - it { expect(@blob_path).to be_allowed_for master } - it { expect(@blob_path).to be_allowed_for reporter } - it { expect(@blob_path).to be_allowed_for :admin } - it { expect(@blob_path).to be_allowed_for guest } - it { expect(@blob_path).to be_allowed_for :user } - it { expect(@blob_path).to be_allowed_for :visitor } - end - - describe "GET /:project_path/edit" do - subject { edit_namespace_project_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/deploy_keys" do - subject { namespace_project_deploy_keys_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/issues" do - subject { namespace_project_issues_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/snippets/new" do - subject { new_namespace_project_snippet_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/merge_requests" do - subject { namespace_project_merge_requests_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/merge_requests/new" do - subject { new_namespace_project_merge_request_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end - - describe "GET /:project_path/branches" do - subject { namespace_project_branches_path(project.namespace, project) } - - before do - # Speed increase - allow_any_instance_of(Project).to receive(:branches).and_return([]) - end - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/tags" do - subject { namespace_project_tags_path(project.namespace, project) } - - before do - # Speed increase - allow_any_instance_of(Project).to receive(:tags).and_return([]) - end - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_allowed_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_allowed_for guest } - it { is_expected.to be_allowed_for :user } - it { is_expected.to be_allowed_for :visitor } - end - - describe "GET /:project_path/hooks" do - subject { namespace_project_hooks_path(project.namespace, project) } - - it { is_expected.to be_allowed_for master } - it { is_expected.to be_denied_for reporter } - it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for guest } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } - end -end diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb deleted file mode 100644 index 4cfaab03caf0a7737534eac6a9101bfc853c90e3..0000000000000000000000000000000000000000 --- a/spec/features/users_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'spec_helper' - -feature 'Users' do - around do |ex| - old_url_options = Rails.application.routes.default_url_options - Rails.application.routes.default_url_options = { host: 'example.foo' } - ex.run - Rails.application.routes.default_url_options = old_url_options - end - - scenario 'GET /users/sign_in creates a new user account' do - visit new_user_session_path - fill_in 'user_name', with: 'Name Surname' - fill_in 'user_username', with: 'Great' - fill_in 'user_email', with: 'name@mail.com' - fill_in 'user_password_sign_up', with: 'password1234' - expect { click_button 'Sign up' }.to change { User.count }.by(1) - end - - scenario 'Successful user signin invalidates password reset token' do - user = create(:user) - expect(user.reset_password_token).to be_nil - - visit new_user_password_path - fill_in 'user_email', with: user.email - click_button 'Reset password' - - user.reload - expect(user.reset_password_token).not_to be_nil - - login_with(user) - expect(current_path).to eq root_path - - user.reload - expect(user.reset_password_token).to be_nil - end -end diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb deleted file mode 100644 index 479fa950387abfbb1e8921f71e5b6c3da9a0940d..0000000000000000000000000000000000000000 --- a/spec/finders/issues_finder_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -require 'spec_helper' - -describe IssuesFinder do - let(:user) { create :user } - let(:user2) { create :user } - let(:project1) { create(:project) } - let(:project2) { create(:project) } - let(:milestone) { create(:milestone, project: project1) } - let(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone) } - let(:issue2) { create(:issue, author: user, assignee: user, project: project2) } - let(:issue3) { create(:issue, author: user2, assignee: user2, project: project2) } - - before do - project1.team << [user, :master] - project2.team << [user, :developer] - project2.team << [user2, :developer] - end - - describe :execute do - before :each do - issue1 - issue2 - issue3 - end - - context 'scope: all' do - it 'should filter by all' do - params = { scope: "all", state: 'opened' } - issues = IssuesFinder.new.execute(user, params) - expect(issues.size).to eq(3) - end - - it 'should filter by assignee id' do - params = { scope: "all", assignee_id: user.id, state: 'opened' } - issues = IssuesFinder.new.execute(user, params) - expect(issues.size).to eq(2) - end - - it 'should filter by author id' do - params = { scope: "all", author_id: user2.id, state: 'opened' } - issues = IssuesFinder.new.execute(user, params) - expect(issues).to eq([issue3]) - end - - it 'should filter by milestone id' do - params = { scope: "all", milestone_id: milestone.id, state: 'opened' } - issues = IssuesFinder.new.execute(user, params) - expect(issues).to eq([issue1]) - end - - it 'should be empty for unauthorized user' do - params = { scope: "all", state: 'opened' } - issues = IssuesFinder.new.execute(nil, params) - expect(issues.size).to be_zero - end - - it 'should not include unauthorized issues' do - params = { scope: "all", state: 'opened' } - issues = IssuesFinder.new.execute(user2, params) - expect(issues.size).to eq(2) - expect(issues).not_to include(issue1) - expect(issues).to include(issue2) - expect(issues).to include(issue3) - end - end - - context 'personal scope' do - it 'should filter by assignee' do - params = { scope: "assigned-to-me", state: 'opened' } - issues = IssuesFinder.new.execute(user, params) - expect(issues.size).to eq(2) - end - - it 'should filter by project' do - params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id } - issues = IssuesFinder.new.execute(user, params) - expect(issues.size).to eq(1) - end - end - end -end diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb deleted file mode 100644 index 8536377a7f079b534fd8ea9e728ee728e003ce86..0000000000000000000000000000000000000000 --- a/spec/finders/merge_requests_finder_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'spec_helper' - -describe MergeRequestsFinder do - let(:user) { create :user } - let(:user2) { create :user } - - let(:project1) { create(:project) } - let(:project2) { create(:project, forked_from_project: project1) } - - let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) } - let!(:merge_request2) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1, state: 'closed') } - let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2) } - - before do - project1.team << [user, :master] - project2.team << [user, :developer] - project2.team << [user2, :developer] - end - - describe "#execute" do - it 'should filter by scope' do - params = { scope: 'authored', state: 'opened' } - merge_requests = MergeRequestsFinder.new.execute(user, params) - expect(merge_requests.size).to eq(2) - end - - it 'should filter by project' do - params = { project_id: project1.id, scope: 'authored', state: 'opened' } - merge_requests = MergeRequestsFinder.new.execute(user, params) - expect(merge_requests.size).to eq(1) - end - end -end diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb deleted file mode 100644 index c83824b900de0678ce22ebbe70be1bc237005113..0000000000000000000000000000000000000000 --- a/spec/finders/notes_finder_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -require 'spec_helper' - -describe NotesFinder do - let(:user) { create :user } - let(:project) { create :project } - let(:note1) { create :note_on_commit, project: project } - let(:note2) { create :note_on_commit, project: project } - let(:commit) { note1.noteable } - - before do - project.team << [user, :master] - end - - describe :execute do - let(:params) { { target_id: commit.id, target_type: 'commit', last_fetched_at: 1.hour.ago.to_i } } - - before do - note1 - note2 - end - - it 'should find all notes' do - notes = NotesFinder.new.execute(project, user, params) - expect(notes.size).to eq(2) - end - - it 'should raise an exception for an invalid target_type' do - params.merge!(target_type: 'invalid') - expect { NotesFinder.new.execute(project, user, params) }.to raise_error('invalid target_type') - end - - it 'filters out old notes' do - note2.update_attribute(:updated_at, 2.hours.ago) - notes = NotesFinder.new.execute(project, user, params) - expect(notes).to eq([note1]) - end - end -end diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb deleted file mode 100644 index 2ab71b05968f81d20bc997f6ed2199e261dcad91..0000000000000000000000000000000000000000 --- a/spec/finders/projects_finder_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'spec_helper' - -describe ProjectsFinder do - let(:user) { create :user } - let(:group) { create :group } - - let(:project1) { create(:empty_project, :public, group: group) } - let(:project2) { create(:empty_project, :internal, group: group) } - let(:project3) { create(:empty_project, :private, group: group) } - let(:project4) { create(:empty_project, :private, group: group) } - - context 'non authenticated' do - subject { ProjectsFinder.new.execute(nil, group: group) } - - it { is_expected.to include(project1) } - it { is_expected.not_to include(project2) } - it { is_expected.not_to include(project3) } - it { is_expected.not_to include(project4) } - end - - context 'authenticated' do - subject { ProjectsFinder.new.execute(user, group: group) } - - it { is_expected.to include(project1) } - it { is_expected.to include(project2) } - it { is_expected.not_to include(project3) } - it { is_expected.not_to include(project4) } - end - - context 'authenticated, project member' do - before { project3.team << [user, :developer] } - - subject { ProjectsFinder.new.execute(user, group: group) } - - it { is_expected.to include(project1) } - it { is_expected.to include(project2) } - it { is_expected.to include(project3) } - it { is_expected.not_to include(project4) } - end - - context 'authenticated, group member' do - before { group.add_user(user, Gitlab::Access::DEVELOPER) } - - subject { ProjectsFinder.new.execute(user, group: group) } - - it { is_expected.to include(project1) } - it { is_expected.to include(project2) } - it { is_expected.to include(project3) } - it { is_expected.to include(project4) } - end -end diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb deleted file mode 100644 index 1b4ffc2d7176e1fa2ef6d896c467c747c00f1323..0000000000000000000000000000000000000000 --- a/spec/finders/snippets_finder_spec.rb +++ /dev/null @@ -1,101 +0,0 @@ -require 'spec_helper' - -describe SnippetsFinder do - let(:user) { create :user } - let(:user1) { create :user } - let(:group) { create :group } - - let(:project1) { create(:empty_project, :public, group: group) } - let(:project2) { create(:empty_project, :private, group: group) } - - - context ':all filter' do - before do - @snippet1 = create(:personal_snippet, visibility_level: Snippet::PRIVATE) - @snippet2 = create(:personal_snippet, visibility_level: Snippet::INTERNAL) - @snippet3 = create(:personal_snippet, visibility_level: Snippet::PUBLIC) - end - - it "returns all private and internal snippets" do - snippets = SnippetsFinder.new.execute(user, filter: :all) - expect(snippets).to include(@snippet2, @snippet3) - expect(snippets).not_to include(@snippet1) - end - - it "returns all public snippets" do - snippets = SnippetsFinder.new.execute(nil, filter: :all) - expect(snippets).to include(@snippet3) - expect(snippets).not_to include(@snippet1, @snippet2) - end - end - - context ':by_user filter' do - before do - @snippet1 = create(:personal_snippet, visibility_level: Snippet::PRIVATE, author: user) - @snippet2 = create(:personal_snippet, visibility_level: Snippet::INTERNAL, author: user) - @snippet3 = create(:personal_snippet, visibility_level: Snippet::PUBLIC, author: user) - end - - it "returns all public and internal snippets" do - snippets = SnippetsFinder.new.execute(user1, filter: :by_user, user: user) - expect(snippets).to include(@snippet2, @snippet3) - expect(snippets).not_to include(@snippet1) - end - - it "returns internal snippets" do - snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user, scope: "are_internal") - expect(snippets).to include(@snippet2) - expect(snippets).not_to include(@snippet1, @snippet3) - end - - it "returns private snippets" do - snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user, scope: "are_private") - expect(snippets).to include(@snippet1) - expect(snippets).not_to include(@snippet2, @snippet3) - end - - it "returns public snippets" do - snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user, scope: "are_public") - expect(snippets).to include(@snippet3) - expect(snippets).not_to include(@snippet1, @snippet2) - end - - it "returns all snippets" do - snippets = SnippetsFinder.new.execute(user, filter: :by_user, user: user) - expect(snippets).to include(@snippet1, @snippet2, @snippet3) - end - - it "returns only public snippets if unauthenticated user" do - snippets = SnippetsFinder.new.execute(nil, filter: :by_user, user: user) - expect(snippets).to include(@snippet3) - expect(snippets).not_to include(@snippet2, @snippet1) - end - - end - - context 'by_project filter' do - before do - @snippet1 = create(:project_snippet, visibility_level: Snippet::PRIVATE, project: project1) - @snippet2 = create(:project_snippet, visibility_level: Snippet::INTERNAL, project: project1) - @snippet3 = create(:project_snippet, visibility_level: Snippet::PUBLIC, project: project1) - end - - it "returns public snippets for unauthorized user" do - snippets = SnippetsFinder.new.execute(nil, filter: :by_project, project: project1) - expect(snippets).to include(@snippet3) - expect(snippets).not_to include(@snippet1, @snippet2) - end - - it "returns public and internal snippets for none project members" do - snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1) - expect(snippets).to include(@snippet2, @snippet3) - expect(snippets).not_to include(@snippet1) - end - - it "returns all snippets for project members" do - project1.team << [user, :developer] - snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1) - expect(snippets).to include(@snippet1, @snippet2, @snippet3) - end - end -end diff --git a/spec/fixtures/GoogleCodeProjectHosting.json b/spec/fixtures/GoogleCodeProjectHosting.json deleted file mode 100644 index d05e77271ae0be5bf96dee120a9ea69e0c776ad8..0000000000000000000000000000000000000000 --- a/spec/fixtures/GoogleCodeProjectHosting.json +++ /dev/null @@ -1,407 +0,0 @@ -{ - "kind" : "projecthosting#user", - "id" : "@WRRVSlFXARlCVgB6", - "projects" : [ { - "kind" : "projecthosting#project", - "name" : "pmn", - "externalId" : "pmn", - "htmlLink" : "/p/pmn/", - "summary" : "Shows an icon in the system tray when you have new emails", - "description" : "IMAP client that shows an icon in the system tray when you have new emails.", - "labels" : [ "Mail" ], - "versionControlSystem" : "svn", - "repositoryUrls" : [ "https://pmn.googlecode.com/svn/" ], - "issuesConfig" : { - "kind" : "projecthosting#projectIssueConfig", - "statuses" : [ { - "status" : "New", - "meansOpen" : true, - "description" : "Issue has not had initial review yet" - }, { - "status" : "Accepted", - "meansOpen" : true, - "description" : "Problem reproduced / Need acknowledged" - }, { - "status" : "Started", - "meansOpen" : true, - "description" : "Work on this issue has begun" - }, { - "status" : "Fixed", - "meansOpen" : false, - "description" : "Developer made source code changes, QA should verify" - }, { - "status" : "Verified", - "meansOpen" : false, - "description" : "QA has verified that the fix worked" - }, { - "status" : "Invalid", - "meansOpen" : false, - "description" : "This was not a valid issue report" - }, { - "status" : "Duplicate", - "meansOpen" : false, - "description" : "This report duplicates an existing issue" - }, { - "status" : "WontFix", - "meansOpen" : false, - "description" : "We decided to not take action on this issue" - }, { - "status" : "Done", - "meansOpen" : false, - "description" : "The requested non-coding task was completed" - } ], - "labels" : [ { - "label" : "Type-Defect", - "description" : "Report of a software defect" - }, { - "label" : "Type-Enhancement", - "description" : "Request for enhancement" - }, { - "label" : "Type-Task", - "description" : "Work item that doesn't change the code or docs" - }, { - "label" : "Type-Review", - "description" : "Request for a source code review" - }, { - "label" : "Type-Other", - "description" : "Some other kind of issue" - }, { - "label" : "Priority-Critical", - "description" : "Must resolve in the specified milestone" - }, { - "label" : "Priority-High", - "description" : "Strongly want to resolve in the specified milestone" - }, { - "label" : "Priority-Medium", - "description" : "Normal priority" - }, { - "label" : "Priority-Low", - "description" : "Might slip to later milestone" - }, { - "label" : "OpSys-All", - "description" : "Affects all operating systems" - }, { - "label" : "OpSys-Windows", - "description" : "Affects Windows users" - }, { - "label" : "OpSys-Linux", - "description" : "Affects Linux users" - }, { - "label" : "OpSys-OSX", - "description" : "Affects Mac OS X users" - }, { - "label" : "Milestone-Release1.0", - "description" : "All essential functionality working" - }, { - "label" : "Component-UI", - "description" : "Issue relates to program UI" - }, { - "label" : "Component-Logic", - "description" : "Issue relates to application logic" - }, { - "label" : "Component-Persistence", - "description" : "Issue relates to data storage components" - }, { - "label" : "Component-Scripts", - "description" : "Utility and installation scripts" - }, { - "label" : "Component-Docs", - "description" : "Issue relates to end-user documentation" - }, { - "label" : "Security", - "description" : "Security risk to users" - }, { - "label" : "Performance", - "description" : "Performance issue" - }, { - "label" : "Usability", - "description" : "Affects program usability" - }, { - "label" : "Maintainability", - "description" : "Hinders future changes" - } ], - "prompts" : [ { - "name" : "Defect report from user", - "title" : "Enter one-line summary", - "description" : "What steps will reproduce the problem?\n1. \n2. \n3. \n\nWhat is the expected output? What do you see instead?\n\n\nWhat version of the product are you using? On what operating system?\n\n\nPlease provide any additional information below.\n", - "titleMustBeEdited" : true, - "status" : "New", - "labels" : [ "Type-Defect", "Priority-Medium" ] - }, { - "name" : "Defect report from developer", - "title" : "Enter one-line summary", - "description" : "What steps will reproduce the problem?\n1. \n2. \n3. \n\nWhat is the expected output? What do you see instead?\n\n\nPlease use labels and text to provide additional information.\n", - "titleMustBeEdited" : true, - "status" : "Accepted", - "labels" : [ "Type-Defect", "Priority-Medium" ], - "membersOnly" : true - }, { - "name" : "Review request", - "title" : "Code review request", - "description" : "Branch name:\n\nPurpose of code changes on this branch:\n\n\nWhen reviewing my code changes, please focus on:\n\n\nAfter the review, I'll merge this branch into:\n/trunk\n", - "status" : "New", - "labels" : [ "Type-Review", "Priority-Medium" ], - "membersOnly" : true, - "defaultToMember" : false - } ], - "defaultPromptForMembers" : 1, - "defaultPromptForNonMembers" : 0 - }, - "role" : "owner", - "members" : [ { - "kind" : "projecthosting#issuePerson", - "name" : "mrovi9000", - "htmlLink" : "https://code.google.com/u/106736353629303906862/" - } ], - "issues" : { - "kind" : "projecthosting#issueList", - "totalResults" : 0, - "items" : [ ] - } - }, { - "kind" : "projecthosting#project", - "name" : "tint2", - "externalId" : "tint2", - "htmlLink" : "/p/tint2/", - "summary" : "tint2 is a lightweight panel/taskbar.", - "description" : "tint2 is a simple _*panel/taskbar*_ unintrusive and light (memory / cpu / aestetic).
    We follow freedesktop specifications.\r\n \r\n=== 0.11 features ===\r\n * panel with taskbar, systray, clock and battery status\r\n * easy to customize : color/transparency on font, icon, border and background\r\n * pager like capability : send task from one workspace to another, switch workspace\r\n * multi-monitor capability : one panel per monitor, show task from current monitor\r\n * customize mouse event\r\n * window manager's menu\r\n * tooltip\r\n * autohide\r\n * clock timezones\r\n * real & fake transparency with autodetection of composite manager\r\n * panel's theme switcher 'tint2conf' \r\n\r\n=== Other project ===\r\n * Lightweight volume control http://softwarebakery.com/maato/volumeicon.html\r\n * Lightweight calendar http://code.google.com/p/gsimplecal/\r\n * Graphical config tool http://code.google.com/p/tintwizard/\r\n * Command line theme switcher http://github.com/dbbolton/scripts/blob/master/tint2theme\r\n\r\n\r\n=== Snapshot SVN ===\r\n\r\nhttp://img252.imageshack.us/img252/1433/wallpaper2td.jpg\r\n\r\n\r\n", - "labels" : [ "taskbar", "panel", "lightweight", "desktop", "openbox", "pager", "tint2" ], - "versionControlSystem" : "git", - "repositoryUrls" : [ "https://tint2.googlecode.com/git/" ], - "issuesConfig" : { - "kind" : "projecthosting#projectIssueConfig", - "defaultColumns" : [ "ID", "Status", "Type", "Milestone", "Priority", "Component", "Owner", "Summary", "Modified", "Stars" ], - "defaultSorting" : [ "-ID" ], - "statuses" : [ { - "status" : "New", - "meansOpen" : true, - "description" : "Issue has not had initial review yet" - }, { - "status" : "NeedInfo", - "meansOpen" : true, - "description" : "More information is needed before deciding what action should be taken" - }, { - "status" : "Accepted", - "meansOpen" : true, - "description" : "A Defect that a developer has reproduced or an Enhancement that a developer has committed to addressing" - }, { - "status" : "Wishlist", - "meansOpen" : true, - "description" : "An Enhancement which is valid, but no developers have committed to addressing" - }, { - "status" : "Started", - "meansOpen" : true, - "description" : "Work on this issue has begun" - }, { - "status" : "Fixed", - "meansOpen" : false, - "description" : "Work has completed" - }, { - "status" : "Invalid", - "meansOpen" : false, - "description" : "This was not a valid issue report" - }, { - "status" : "Duplicate", - "meansOpen" : false, - "description" : "This report duplicates an existing issue" - }, { - "status" : "WontFix", - "meansOpen" : false, - "description" : "We decided to not take action on this issue" - }, { - "status" : "Incomplete", - "meansOpen" : false, - "description" : "Not enough information and no activity for a long period of time" - } ], - "labels" : [ { - "label" : "Type-Defect", - "description" : "Report of a software defect" - }, { - "label" : "Type-Enhancement", - "description" : "Request for enhancement" - }, { - "label" : "Type-Task", - "description" : "Work item that does not change the code" - }, { - "label" : "Type-Review", - "description" : "Request for a source code review" - }, { - "label" : "Type-Other", - "description" : "Some other kind of issue" - }, { - "label" : "Milestone-0.12", - "description" : "Fix should be included in release 0.12" - }, { - "label" : "Priority-Critical", - "description" : "Must resolve in the specified milestone" - }, { - "label" : "Priority-High", - "description" : "Strongly want to resolve in the specified milestone" - }, { - "label" : "Priority-Medium", - "description" : "Normal priority" - }, { - "label" : "Priority-Low", - "description" : "Might slip to later milestone" - }, { - "label" : "OpSys-All", - "description" : "Affects all operating systems" - }, { - "label" : "OpSys-Windows", - "description" : "Affects Windows users" - }, { - "label" : "OpSys-Linux", - "description" : "Affects Linux users" - }, { - "label" : "OpSys-OSX", - "description" : "Affects Mac OS X users" - }, { - "label" : "Security", - "description" : "Security risk to users" - }, { - "label" : "Performance", - "description" : "Performance issue" - }, { - "label" : "Usability", - "description" : "Affects program usability" - }, { - "label" : "Maintainability", - "description" : "Hinders future changes" - }, { - "label" : "Component-Panel", - "description" : "Issue relates to the panel (e.g. positioning, hiding, transparency)" - }, { - "label" : "Component-Taskbar", - "description" : "Issue relates to the taskbar (e.g. tasks, multiple desktops)" - }, { - "label" : "Component-Battery", - "description" : "Issue relates to the battery" - }, { - "label" : "Component-Systray", - "description" : "Issue relates to the system tray" - }, { - "label" : "Component-Clock", - "description" : "Issue relates to the clock" - }, { - "label" : "Component-Launcher", - "description" : "Issue relates to the launcher" - }, { - "label" : "Component-Tint2conf", - "description" : "Issue relates to the configuration GUI (tint2conf)" - }, { - "label" : "Component-Docs", - "description" : "Issue relates to end-user documentation" - }, { - "label" : "Component-New", - "description" : "Issue describes a new component proposal" - } ], - "prompts" : [ { - "name" : "Defect report from user", - "title" : "Enter one-line summary", - "description" : "What steps will reproduce the problem?\n1.\n2.\n3.\n\nWhat is the expected output? What do you see instead?\n\n\nWhat version of the product are you using? On what operating system?\n\n\nWhich window manager (e.g. openbox, xfwm, metacity, mutter, kwin) or\nwhich desktop environment (e.g. Gnome 2, Gnome 3, LXDE, XFCE, KDE)\nare you using?\n\n\nPlease provide any additional information below. It might be helpful\nto attach your tint2rc file (usually located at ~/.config/tint2/tint2rc).", - "titleMustBeEdited" : true, - "status" : "New", - "labels" : [ "Priority-Medium" ], - "defaultToMember" : true - }, { - "name" : "Defect report from developer", - "title" : "Enter one-line summary", - "description" : "What steps will reproduce the problem?\n1.\n2.\n3.\n\nWhat is the expected output? What do you see instead?\n\n\nPlease use labels and text to provide additional information.", - "titleMustBeEdited" : true, - "status" : "Accepted", - "labels" : [ "Type-Defect", "Priority-Medium" ], - "membersOnly" : true, - "defaultToMember" : true - }, { - "name" : "Review request", - "title" : "Code review request", - "description" : "Purpose of code changes on this branch:\n\n\nWhen reviewing my code changes, please focus on:\n\n\nAfter the review, I'll merge this branch into:\n/trunk", - "status" : "New", - "labels" : [ "Type-Review", "Priority-Medium" ], - "membersOnly" : true, - "defaultToMember" : true - } ], - "defaultPromptForMembers" : 1, - "defaultPromptForNonMembers" : 0, - "usersCanSetLabels" : false - }, - "role" : "owner", - "issues" : { - "kind" : "projecthosting#issueList", - "totalResults" : 473, - "items" : [ { - "kind" : "projecthosting#issue", - "id" : 169, - "title" : "Scrolling through tasks", - "summary" : "Scrolling through tasks", - "stars" : 1, - "starred" : false, - "status" : "Fixed", - "state" : "closed", - "labels" : [ "Type-Enhancement", "Priority-Medium" ], - "author" : { - "kind" : "projecthosting#issuePerson", - "name" : "schattenpr...", - "htmlLink" : "https://code.google.com/u/106498139506637530000/" - }, - "owner" : { - "kind" : "projecthosting#issuePerson", - "name" : "thilo...", - "htmlLink" : "https://code.google.com/u/104224918623172014000/" - }, - "updated" : "2009-11-18T05:14:58.000Z", - "published" : "2009-11-18T00:20:19.000Z", - "closed" : "2009-11-18T05:14:58.000Z", - "projectId" : "tint2", - "canComment" : true, - "canEdit" : true, - "comments" : { - "kind" : "projecthosting#issueCommentList", - "totalResults" : 2, - "items" : [ { - "id" : 0, - "kind" : "projecthosting#issueComment", - "author" : { - "kind" : "projecthosting#issuePerson", - "name" : "schattenpr...", - "htmlLink" : "https://code.google.com/u/10649813950663753000/" - }, - "content" : "I like to scroll through the tasks with my scrollwheel (like in fluxbox). \r\n\r\nPatch is attached that adds two new mouse-actions (next_task+prev_task) \r\nthat can be used for exactly that purpose. \r\n\r\nall the best!", - "published" : "2009-11-18T00:20:19.000Z", - "updates" : { - "kind" : "projecthosting#issueCommentUpdate" - }, - "canDelete" : true, - "attachments" : [ { - "attachmentId" : "8901002890399325565", - "fileName" : "tint2_task_scrolling.diff", - "fileSize" : 3059, - "mimetype" : "text/x-c++; charset=us-ascii" - }, { - "attachmentId" : "000", - "fileName" : "screenshot.png", - "fileSize" : 0, - "mimetype" : "image/png" - } ] - }, { - "id" : 1, - "kind" : "projecthosting#issueComment", - "author" : { - "kind" : "projecthosting#issuePerson", - "name" : "thilo...", - "htmlLink" : "https://code.google.com/u/104224918623172014000/" - }, - "content" : "applied, thanks.\r\n", - "published" : "2009-11-18T05:14:58.000Z", - "updates" : { - "kind" : "projecthosting#issueCommentUpdate", - "status" : "Fixed", - "labels" : [ "-Type-Defect", "Type-Enhancement" ] - }, - "canDelete" : true - } ] - } - } ] - } - } ] -} diff --git a/spec/fixtures/banana_sample.gif b/spec/fixtures/banana_sample.gif deleted file mode 100644 index 1322ac92d141f2240f3b68b1c4a10b5e18b49e2b..0000000000000000000000000000000000000000 Binary files a/spec/fixtures/banana_sample.gif and /dev/null differ diff --git a/spec/fixtures/dk.png b/spec/fixtures/dk.png deleted file mode 100644 index 87ce25e877ab8a9602b77af019f191e6749003f9..0000000000000000000000000000000000000000 Binary files a/spec/fixtures/dk.png and /dev/null differ diff --git a/spec/fixtures/doc_sample.txt b/spec/fixtures/doc_sample.txt deleted file mode 100644 index 600477e9421e2d06e2f1e6e716e76ce1d52b8c57..0000000000000000000000000000000000000000 --- a/spec/fixtures/doc_sample.txt +++ /dev/null @@ -1,3 +0,0 @@ -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - -Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? diff --git a/spec/fixtures/rails_sample.jpg b/spec/fixtures/rails_sample.jpg deleted file mode 100644 index a847b19332535844fe83840e16d3872902bb7441..0000000000000000000000000000000000000000 Binary files a/spec/fixtures/rails_sample.jpg and /dev/null differ diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb deleted file mode 100644 index 015a66f7fa02a46fc39d09137e2de0a2fc67d3cf..0000000000000000000000000000000000000000 --- a/spec/helpers/application_helper_spec.rb +++ /dev/null @@ -1,262 +0,0 @@ -require 'spec_helper' - -describe ApplicationHelper do - describe 'current_controller?' do - before do - allow(controller).to receive(:controller_name).and_return('foo') - end - - it 'returns true when controller matches argument' do - expect(current_controller?(:foo)).to be_truthy - end - - it 'returns false when controller does not match argument' do - expect(current_controller?(:bar)).not_to be_truthy - end - - it 'should take any number of arguments' do - expect(current_controller?(:baz, :bar)).not_to be_truthy - expect(current_controller?(:baz, :bar, :foo)).to be_truthy - end - end - - describe 'current_action?' do - before do - allow(self).to receive(:action_name).and_return('foo') - end - - it 'returns true when action matches argument' do - expect(current_action?(:foo)).to be_truthy - end - - it 'returns false when action does not match argument' do - expect(current_action?(:bar)).not_to be_truthy - end - - it 'should take any number of arguments' do - expect(current_action?(:baz, :bar)).not_to be_truthy - expect(current_action?(:baz, :bar, :foo)).to be_truthy - end - end - - describe 'project_icon' do - avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png') - - it 'should return an url for the avatar' do - project = create(:project) - project.avatar = File.open(avatar_file_path) - project.save! - avatar_url = "http://localhost/uploads/project/avatar/#{ project.id }/gitlab_logo.png" - expect(project_icon("#{project.namespace.to_param}/#{project.to_param}").to_s).to eq( - "\"Gitlab" - ) - end - - it 'should give uploaded icon when present' do - project = create(:project) - project.save! - - allow_any_instance_of(Project).to receive(:avatar_in_git).and_return(true) - - avatar_url = 'http://localhost' + namespace_project_avatar_path(project.namespace, project) - expect(project_icon("#{project.namespace.to_param}/#{project.to_param}").to_s).to match( - image_tag(avatar_url)) - end - end - - describe 'avatar_icon' do - avatar_file_path = File.join(Rails.root, 'public', 'gitlab_logo.png') - - it 'should return an url for the avatar' do - user = create(:user) - user.avatar = File.open(avatar_file_path) - user.save! - expect(avatar_icon(user.email).to_s). - to match("/uploads/user/avatar/#{ user.id }/gitlab_logo.png") - end - - it 'should return an url for the avatar with relative url' do - Gitlab.config.gitlab.stub(relative_url_root: '/gitlab') - Gitlab.config.gitlab.stub(url: Settings.send(:build_gitlab_url)) - - user = create(:user) - user.avatar = File.open(avatar_file_path) - user.save! - expect(avatar_icon(user.email).to_s). - to match("/gitlab/uploads/user/avatar/#{ user.id }/gitlab_logo.png") - end - - it 'should call gravatar_icon when no avatar is present' do - user = create(:user, email: 'test@example.com') - user.save! - expect(avatar_icon(user.email).to_s).to eq('http://www.gravatar.com/avatar/55502f40dc8b7c769880b10874abc9d0?s=40&d=identicon') - end - end - - describe 'gravatar_icon' do - let(:user_email) { 'user@email.com' } - - it 'should return a generic avatar path when Gravatar is disabled' do - ApplicationSetting.any_instance.stub(gravatar_enabled?: false) - expect(gravatar_icon(user_email)).to match('no_avatar.png') - end - - it 'should return a generic avatar path when email is blank' do - expect(gravatar_icon('')).to match('no_avatar.png') - end - - it 'should return default gravatar url' do - Gitlab.config.gitlab.stub(https: false) - url = 'http://www.gravatar.com/avatar/b58c6f14d292556214bd64909bcdb118' - expect(gravatar_icon(user_email)).to match(url) - end - - it 'should use SSL when appropriate' do - Gitlab.config.gitlab.stub(https: true) - expect(gravatar_icon(user_email)).to match('https://secure.gravatar.com') - end - - it 'should return custom gravatar path when gravatar_url is set' do - allow(self).to receive(:request).and_return(double(:ssl? => false)) - allow(Gitlab.config.gravatar). - to receive(:plain_url). - and_return('http://example.local/?s=%{size}&hash=%{hash}') - url = 'http://example.local/?s=20&hash=b58c6f14d292556214bd64909bcdb118' - expect(gravatar_icon(user_email, 20)).to eq(url) - end - - it 'should accept a custom size' do - allow(self).to receive(:request).and_return(double(:ssl? => false)) - expect(gravatar_icon(user_email, 64)).to match(/\?s=64/) - end - - it 'should use default size when size is wrong' do - allow(self).to receive(:request).and_return(double(:ssl? => false)) - expect(gravatar_icon(user_email, nil)).to match(/\?s=40/) - end - - it 'should be case insensitive' do - allow(self).to receive(:request).and_return(double(:ssl? => false)) - expect(gravatar_icon(user_email)). - to eq(gravatar_icon(user_email.upcase + ' ')) - end - end - - describe 'grouped_options_refs' do - # Override Rails' grouped_options_for_select helper since HTML is harder to work with - def grouped_options_for_select(options, *args) - options - end - - let(:options) { grouped_options_refs } - - before do - # Must be an instance variable - @project = create(:project) - end - - it 'includes a list of branch names' do - expect(options[0][0]).to eq('Branches') - expect(options[0][1]).to include('master', 'feature') - end - - it 'includes a list of tag names' do - expect(options[1][0]).to eq('Tags') - expect(options[1][1]).to include('v1.0.0', 'v1.1.0') - end - - it 'includes a specific commit ref if defined' do - # Must be an instance variable - @ref = '2ed06dc41dbb5936af845b87d79e05bbf24c73b8' - - expect(options[2][0]).to eq('Commit') - expect(options[2][1]).to eq([@ref]) - end - - it 'sorts tags in a natural order' do - # Stub repository.tag_names to make sure we get some valid testing data - expect(@project.repository).to receive(:tag_names). - and_return(['v1.0.9', 'v1.0.10', 'v2.0', 'v3.1.4.2', 'v2.0rc1¿', - 'v1.0.9a', 'v2.0-rc1', 'v2.0rc2']) - - expect(options[1][1]). - to eq(['v3.1.4.2', 'v2.0', 'v2.0rc2', 'v2.0rc1¿', 'v2.0-rc1', 'v1.0.10', - 'v1.0.9', 'v1.0.9a']) - end - end - - describe 'user_color_scheme_class' do - context 'with current_user is nil' do - it 'should return a string' do - allow(self).to receive(:current_user).and_return(nil) - expect(user_color_scheme_class).to be_kind_of(String) - end - end - - context 'with a current_user' do - (1..5).each do |color_scheme_id| - context "with color_scheme_id == #{color_scheme_id}" do - it 'should return a string' do - current_user = double(:color_scheme_id => color_scheme_id) - allow(self).to receive(:current_user).and_return(current_user) - expect(user_color_scheme_class).to be_kind_of(String) - end - end - end - end - end - - describe 'simple_sanitize' do - let(:a_tag) { 'Foo' } - - it 'allows the a tag' do - expect(simple_sanitize(a_tag)).to eq(a_tag) - end - - it 'allows the span tag' do - input = 'Bar' - expect(simple_sanitize(input)).to eq(input) - end - - it 'disallows other tags' do - input = "#{a_tag}" - expect(simple_sanitize(input)).to eq(a_tag) - end - end - - describe 'link_to' do - it 'should not include rel=nofollow for internal links' do - expect(link_to('Home', root_path)).to eq('Home') - end - - it 'should include rel=nofollow for external links' do - expect(link_to('Example', 'http://www.example.com')). - to eq 'Example' - end - - it 'should include rel=nofollow for external links and honor existing html_options' do - expect(link_to('Example', 'http://www.example.com', class: 'toggle', data: {toggle: 'dropdown'})) - .to eq 'Example' - end - - it 'should include rel=nofollow for external links and preserve other rel values' do - expect(link_to('Example', 'http://www.example.com', rel: 'noreferrer')) - .to eq 'Example' - end - - it 'should not include rel=nofollow for external links on the same host as GitLab' do - expect(Gitlab.config.gitlab).to receive(:host).and_return('example.foo') - expect(link_to('Example', 'http://example.foo/bar')). - to eq 'Example' - end - end - - describe 'markup_render' do - let(:content) { 'Noël' } - - it 'should preserve encoding' do - expect(content.encoding.name).to eq('UTF-8') - expect(render_markup('foo.rst', content).encoding.name).to eq('UTF-8') - end - end -end diff --git a/spec/helpers/broadcast_messages_helper_spec.rb b/spec/helpers/broadcast_messages_helper_spec.rb deleted file mode 100644 index f6df12662bb1a78a44d1647823d8f538979274c6..0000000000000000000000000000000000000000 --- a/spec/helpers/broadcast_messages_helper_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' - -describe BroadcastMessagesHelper do - describe 'broadcast_styling' do - let(:broadcast_message) { double(color: "", font: "") } - - context "default style" do - it "should have no style" do - expect(broadcast_styling(broadcast_message)).to match('') - end - end - - context "customiezd style" do - before { broadcast_message.stub(color: "#f2dede", font: "#b94a48") } - - it "should have a customized style" do - expect(broadcast_styling(broadcast_message)). - to match('background-color:#f2dede;color:#b94a48') - end - end - end -end diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb deleted file mode 100644 index 5bd09793b11dac1209da4d095263dc0b728d1181..0000000000000000000000000000000000000000 --- a/spec/helpers/diff_helper_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -require 'spec_helper' - -describe DiffHelper do - include RepoHelpers - - let(:project) { create(:project) } - let(:commit) { project.repository.commit(sample_commit.id) } - let(:diff) { commit.diffs.first } - let(:diff_file) { Gitlab::Diff::File.new(diff) } - - describe 'diff_hard_limit_enabled?' do - it 'should return true if param is provided' do - allow(controller).to receive(:params) { { force_show_diff: true } } - expect(diff_hard_limit_enabled?).to be_truthy - end - - it 'should return false if param is not provided' do - expect(diff_hard_limit_enabled?).to be_falsey - end - end - - describe 'allowed_diff_size' do - it 'should return hard limit for a diff if force diff is true' do - allow(controller).to receive(:params) { { force_show_diff: true } } - expect(allowed_diff_size).to eq(1000) - end - - it 'should return safe limit for a diff if force diff is false' do - expect(allowed_diff_size).to eq(100) - end - end - - describe 'parallel_diff' do - it 'should return an array of arrays containing the parsed diff' do - expect(parallel_diff(diff_file, 0)). - to match_array(parallel_diff_result_array) - end - end - - describe 'generate_line_code' do - it 'should generate correct line code' do - expect(generate_line_code(diff_file.file_path, diff_file.diff_lines.first)). - to eq('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6') - end - end - - describe 'unfold_bottom_class' do - it 'should return empty string when bottom line shouldnt be unfolded' do - expect(unfold_bottom_class(false)).to eq('') - end - - it 'should return js class when bottom lines should be unfolded' do - expect(unfold_bottom_class(true)).to eq('js-unfold-bottom') - end - end - - describe 'diff_line_content' do - - it 'should return non breaking space when line is empty' do - expect(diff_line_content(nil)).to eq('  ') - end - - it 'should return the line itself' do - expect(diff_line_content(diff_file.diff_lines.first.text)). - to eq('@@ -6,12 +6,18 @@ module Popen') - expect(diff_line_content(diff_file.diff_lines.first.type)).to eq('match') - expect(diff_line_content(diff_file.diff_lines.first.new_pos)).to eq(6) - end - end - - def parallel_diff_result_array - [ - ["match", 6, "@@ -6,12 +6,18 @@ module Popen", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6", "match", 6, "@@ -6,12 +6,18 @@ module Popen", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6"], - [nil, 6, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6", nil, 6, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6"], [nil, 7, " def popen(cmd, path=nil)", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7", nil, 7, " def popen(cmd, path=nil)", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7"], - [nil, 8, " unless cmd.is_a?(Array)", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_8_8", nil, 8, " unless cmd.is_a?(Array)", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_8_8"], - ["old", 9, "- raise "System commands must be given as an array of strings"", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_9_9", "new", 9, "+ raise RuntimeError, "System commands must be given as an array of strings"", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"], - [nil, 10, " end", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_10", nil, 10, " end", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_10"], - [nil, 11, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_11_11", nil, 11, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_11_11"], - [nil, 12, " path ||= Dir.pwd", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_12_12", nil, 12, " path ||= Dir.pwd", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_12_12"], - ["old", 13, "- vars = { "PWD" => path }", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_13_13", "old", nil, " ", nil], - ["old", 14, "- options = { chdir: path }", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_13", "new", 13, "+", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_13"], - [nil, nil, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_14", "new", 14, "+ vars = {", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_14"], - [nil, nil, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_15", "new", 15, "+ "PWD" => path", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_15"], - [nil, nil, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_16", "new", 16, "+ }", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_16"], - [nil, nil, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_17", "new", 17, "+", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_17"], - [nil, nil, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_18", "new", 18, "+ options = {", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_18"], - [nil, nil, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_19", "new", 19, "+ chdir: path", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_19"], - [nil, nil, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_20", "new", 20, "+ }", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_20"], - [nil, 15, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_21", nil, 21, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_21"], - [nil, 16, " unless File.directory?(path)", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_16_22", nil, 22, " unless File.directory?(path)", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_16_22"], - [nil, 17, " FileUtils.mkdir_p(path)", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_17_23", nil, 23, " FileUtils.mkdir_p(path)", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_17_23"], - ["match", 19, "@@ -19,6 +25,7 @@ module Popen", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25", "match", 25, "@@ -19,6 +25,7 @@ module Popen", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25"], - [nil, 19, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25", nil, 25, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25"], - [nil, 20, " @cmd_output = """, "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_20_26", nil, 26, " @cmd_output = """, "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_20_26"], - [nil, 21, " @cmd_status = 0", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_21_27", nil, 27, " @cmd_status = 0", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_21_27"], - [nil, nil, " ", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_28", "new", 28, "+", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_28"], - [nil, 22, " Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_29", nil, 29, " Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_29"], - [nil, 23, " @cmd_output << stdout.read", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_23_30", nil, 30, " @cmd_output << stdout.read", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_23_30"], - [nil, 24, " @cmd_output << stderr.read", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_24_31", nil, 31, " @cmd_output << stderr.read", "2f6fcd96b88b36ce98c38da085c795a27d92a3dd_24_31"] - ] - end -end diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb deleted file mode 100644 index b392371deb4c427d6deb16b472462f8a0b4786e5..0000000000000000000000000000000000000000 --- a/spec/helpers/events_helper_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'spec_helper' - -describe EventsHelper do - include ApplicationHelper - include GitlabMarkdownHelper - - let(:current_user) { create(:user, email: "current@email.com") } - - it 'should display one line of plain text without alteration' do - input = 'A short, plain note' - expect(event_note(input)).to match(input) - expect(event_note(input)).not_to match(/\.\.\.\z/) - end - - it 'should display inline code' do - input = 'A note with `inline code`' - expected = 'A note with inline code' - - expect(event_note(input)).to match(expected) - end - - it 'should truncate a note with multiple paragraphs' do - input = "Paragraph 1\n\nParagraph 2" - expected = 'Paragraph 1...' - - expect(event_note(input)).to match(expected) - end - - it 'should display the first line of a code block' do - input = "```\nCode block\nwith two lines\n```" - expected = '

    ' \
    -               'Code block...
    ' - - expect(event_note(input)).to match(expected) - end - - it 'should truncate a single long line of text' do - text = 'The quick brown fox jumped over the lazy dog twice' # 50 chars - input = "#{text}#{text}#{text}#{text}" # 200 chars - expected = "#{text}#{text}".sub(/.{3}/, '...') - - expect(event_note(input)).to match(expected) - end - - it 'should preserve a link href when link text is truncated' do - text = 'The quick brown fox jumped over the lazy dog' # 44 chars - input = "#{text}#{text}#{text} " # 133 chars - link_url = 'http://example.com/foo/bar/baz' # 30 chars - input << link_url - expected_link_text = 'http://example...' - - expect(event_note(input)).to match(link_url) - expect(event_note(input)).to match(expected_link_text) - end - - it 'should preserve code color scheme' do - input = "```ruby\ndef test\n 'hello world'\nend\n```" - expected = '
    ' \
    -      "def test\n" \
    -      "  \'hello world\'\n" \
    -      "end\n" \
    -      '
    ' - expect(event_note(input)).to eq(expected) - end -end diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb deleted file mode 100644 index 944e743675c7d91cb67007ddb7ed1ba521c53c16..0000000000000000000000000000000000000000 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ /dev/null @@ -1,916 +0,0 @@ -require 'spec_helper' - -describe GitlabMarkdownHelper do - include ApplicationHelper - include IssuesHelper - - # TODO: Properly test this - def can?(*) - true - end - - let!(:project) { create(:project) } - let(:empty_project) { create(:empty_project) } - - let(:user) { create(:user, username: 'gfm') } - let(:commit) { project.repository.commit } - let(:earlier_commit){ project.repository.commit("HEAD~2") } - let(:issue) { create(:issue, project: project) } - let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let(:snippet) { create(:project_snippet, project: project) } - let(:member) { project.project_members.where(user_id: user).first } - - # Helper expects a current_user method. - let(:current_user) { user } - - def url_helper(image_name) - File.join(root_url, 'assets', image_name) - end - - before do - # Helper expects a @project instance variable - @project = project - @ref = 'markdown' - @repository = project.repository - @request.host = Gitlab.config.gitlab.host - end - - describe "#gfm" do - it "should return unaltered text if project is nil" do - actual = "Testing references: ##{issue.iid}" - - expect(gfm(actual)).not_to eq(actual) - - @project = nil - expect(gfm(actual)).to eq(actual) - end - - it "should not alter non-references" do - actual = expected = "_Please_ *stop* 'helping' and all the other b*$#%' you do." - expect(gfm(actual)).to eq(expected) - end - - it "should not touch HTML entities" do - allow(@project.issues).to receive(:where). - with(id: '39').and_return([issue]) - actual = 'We'll accept good pull requests.' - expect(gfm(actual)).to eq("We'll accept good pull requests.") - end - - it "should forward HTML options to links" do - expect(gfm("Fixed in #{commit.id}", @project, class: 'foo')). - to have_selector('a.gfm.foo') - end - - describe "referencing a commit range" do - let(:expected) { namespace_project_compare_path(project.namespace, project, from: earlier_commit.id, to: commit.id) } - - it "should link using a full id" do - actual = "What happened in #{earlier_commit.id}...#{commit.id}" - expect(gfm(actual)).to match(expected) - end - - it "should link using a short id" do - actual = "What happened in #{earlier_commit.short_id}...#{commit.short_id}" - expected = namespace_project_compare_path(project.namespace, project, from: earlier_commit.short_id, to: commit.short_id) - expect(gfm(actual)).to match(expected) - end - - it "should link inclusively" do - actual = "What happened in #{earlier_commit.id}..#{commit.id}" - expected = namespace_project_compare_path(project.namespace, project, from: "#{earlier_commit.id}^", to: commit.id) - expect(gfm(actual)).to match(expected) - end - - it "should link with adjacent text" do - actual = "(see #{earlier_commit.id}...#{commit.id})" - expect(gfm(actual)).to match(expected) - end - - it "should keep whitespace intact" do - actual = "Changes #{earlier_commit.id}...#{commit.id} dramatically" - expected = /Changes #{earlier_commit.id}...#{commit.id}<\/a> dramatically/ - expect(gfm(actual)).to match(expected) - end - - it "should not link with an invalid id" do - actual = expected = "What happened in #{earlier_commit.id.reverse}...#{commit.id.reverse}" - expect(gfm(actual)).to eq(expected) - end - - it "should include a title attribute" do - actual = "What happened in #{earlier_commit.id}...#{commit.id}" - expect(gfm(actual)).to match(/title="Commits #{earlier_commit.id} through #{commit.id}"/) - end - - it "should include standard gfm classes" do - actual = "What happened in #{earlier_commit.id}...#{commit.id}" - expect(gfm(actual)).to match(/class="\s?gfm gfm-commit_range\s?"/) - end - end - - describe "referencing a commit" do - let(:expected) { namespace_project_commit_path(project.namespace, project, commit) } - - it "should link using a full id" do - actual = "Reverts #{commit.id}" - expect(gfm(actual)).to match(expected) - end - - it "should link using a short id" do - actual = "Backported from #{commit.short_id}" - expect(gfm(actual)).to match(expected) - end - - it "should link with adjacent text" do - actual = "Reverted (see #{commit.id})" - expect(gfm(actual)).to match(expected) - end - - it "should keep whitespace intact" do - actual = "Changes #{commit.id} dramatically" - expected = /Changes #{commit.id}<\/a> dramatically/ - expect(gfm(actual)).to match(expected) - end - - it "should not link with an invalid id" do - actual = expected = "What happened in #{commit.id.reverse}" - expect(gfm(actual)).to eq(expected) - end - - it "should include a title attribute" do - actual = "Reverts #{commit.id}" - expect(gfm(actual)).to match(/title="#{commit.link_title}"/) - end - - it "should include standard gfm classes" do - actual = "Reverts #{commit.id}" - expect(gfm(actual)).to match(/class="\s?gfm gfm-commit\s?"/) - end - end - - describe "referencing a team member" do - let(:actual) { "@#{user.username} you are right." } - let(:expected) { user_path(user) } - - before do - project.team << [user, :master] - end - - it "should link using a simple name" do - expect(gfm(actual)).to match(expected) - end - - it "should link using a name with dots" do - user.update_attributes(name: "alphA.Beta") - expect(gfm(actual)).to match(expected) - end - - it "should link using name with underscores" do - user.update_attributes(name: "ping_pong_king") - expect(gfm(actual)).to match(expected) - end - - it "should link with adjacent text" do - actual = "Mail the admin (@#{user.username})" - expect(gfm(actual)).to match(expected) - end - - it "should keep whitespace intact" do - actual = "Yes, @#{user.username} is right." - expected = /Yes, @#{user.username}<\/a> is right/ - expect(gfm(actual)).to match(expected) - end - - it "should not link with an invalid id" do - actual = expected = "@#{user.username.reverse} you are right." - expect(gfm(actual)).to eq(expected) - end - - it "should include standard gfm classes" do - expect(gfm(actual)).to match(/class="\s?gfm gfm-project_member\s?"/) - end - end - - # Shared examples for referencing an object - # - # Expects the following attributes to be available in the example group: - # - # - object - The object itself - # - reference - The object reference string (e.g., #1234, $1234, !1234) - # - # Currently limited to Snippets, Issues and MergeRequests - shared_examples 'referenced object' do - let(:actual) { "Reference to #{reference}" } - let(:expected) { polymorphic_path([project.namespace, project, object]) } - - it "should link using a valid id" do - expect(gfm(actual)).to match(expected) - end - - it "should link with adjacent text" do - # Wrap the reference in parenthesis - expect(gfm(actual.gsub(reference, "(#{reference})"))).to match(expected) - - # Append some text to the end of the reference - expect(gfm(actual.gsub(reference, "#{reference}, right?"))). - to match(expected) - end - - it "should keep whitespace intact" do - actual = "Referenced #{reference} already." - expected = /Referenced [^\s]+<\/a> already/ - expect(gfm(actual)).to match(expected) - end - - it "should not link with an invalid id" do - # Modify the reference string so it's still parsed, but is invalid - reference.gsub!(/^(.)(\d+)$/, '\1' + ('\2' * 2)) - expect(gfm(actual)).to eq(actual) - end - - it "should include a title attribute" do - title = "#{object.class.to_s.titlecase}: #{object.title}" - expect(gfm(actual)).to match(/title="#{title}"/) - end - - it "should include standard gfm classes" do - css = object.class.to_s.underscore - expect(gfm(actual)).to match(/class="\s?gfm gfm-#{css}\s?"/) - end - end - - # Shared examples for referencing an object in a different project - # - # Expects the following attributes to be available in the example group: - # - # - object - The object itself - # - reference - The object reference string (e.g., #1234, $1234, !1234) - # - other_project - The project that owns the target object - # - # Currently limited to Snippets, Issues and MergeRequests - shared_examples 'cross-project referenced object' do - let(:project_path) { @other_project.path_with_namespace } - let(:full_reference) { "#{project_path}#{reference}" } - let(:actual) { "Reference to #{full_reference}" } - let(:expected) do - if object.is_a?(Commit) - namespace_project_commit_path(@other_project.namespace, @other_project, object) - else - polymorphic_path([@other_project.namespace, @other_project, object]) - end - end - - it 'should link using a valid id' do - expect(gfm(actual)).to match( - /#{expected}.*#{Regexp.escape(full_reference)}/ - ) - end - - it 'should link with adjacent text' do - # Wrap the reference in parenthesis - expect(gfm(actual.gsub(full_reference, "(#{full_reference})"))).to( - match(expected) - ) - - # Append some text to the end of the reference - expect(gfm(actual.gsub(full_reference, "#{full_reference}, right?"))). - to(match(expected)) - end - - it 'should keep whitespace intact' do - actual = "Referenced #{full_reference} already." - expected = /Referenced [^\s]+<\/a> already/ - expect(gfm(actual)).to match(expected) - end - - it 'should not link with an invalid id' do - # Modify the reference string so it's still parsed, but is invalid - if object.is_a?(Commit) - reference.gsub!(/^(.).+$/, '\1' + '12345abcd') - else - reference.gsub!(/^(.)(\d+)$/, '\1' + ('\2' * 2)) - end - expect(gfm(actual)).to eq(actual) - end - - it 'should include a title attribute' do - if object.is_a?(Commit) - title = object.link_title - else - title = "#{object.class.to_s.titlecase}: #{object.title}" - end - expect(gfm(actual)).to match(/title="#{title}"/) - end - - it 'should include standard gfm classes' do - css = object.class.to_s.underscore - expect(gfm(actual)).to match(/class="\s?gfm gfm-#{css}\s?"/) - end - end - - describe "referencing an issue" do - let(:object) { issue } - let(:reference) { "##{issue.iid}" } - - include_examples 'referenced object' - end - - context 'cross-repo references' do - before(:all) do - @other_project = create(:project, :public) - @commit2 = @other_project.repository.commit - @issue2 = create(:issue, project: @other_project) - @merge_request2 = create(:merge_request, - source_project: @other_project, - target_project: @other_project) - end - - describe 'referencing an issue in another project' do - let(:object) { @issue2 } - let(:reference) { "##{@issue2.iid}" } - - include_examples 'cross-project referenced object' - end - - describe 'referencing an merge request in another project' do - let(:object) { @merge_request2 } - let(:reference) { "!#{@merge_request2.iid}" } - - include_examples 'cross-project referenced object' - end - - describe 'referencing a commit in another project' do - let(:object) { @commit2 } - let(:reference) { "@#{@commit2.id}" } - - include_examples 'cross-project referenced object' - end - end - - describe "referencing a Jira issue" do - let(:actual) { "Reference to JIRA-#{issue.iid}" } - let(:expected) { "http://jira.example/browse/JIRA-#{issue.iid}" } - let(:reference) { "JIRA-#{issue.iid}" } - - before do - jira = @project.create_jira_service if @project.jira_service.nil? - properties = {"title"=>"JIRA tracker", "project_url"=>"http://jira.example/issues/?jql=project=A", "issues_url"=>"http://jira.example/browse/:id", "new_issue_url"=>"http://jira.example/secure/CreateIssue.jspa"} - jira.update_attributes(properties: properties, active: true) - end - - after do - @project.jira_service.destroy! unless @project.jira_service.nil? - end - - it "should link using a valid id" do - expect(gfm(actual)).to match(expected) - end - - it "should link with adjacent text" do - # Wrap the reference in parenthesis - expect(gfm(actual.gsub(reference, "(#{reference})"))).to match(expected) - - # Append some text to the end of the reference - expect(gfm(actual.gsub(reference, "#{reference}, right?"))). - to match(expected) - end - - it "should keep whitespace intact" do - actual = "Referenced #{reference} already." - expected = /Referenced [^\s]+<\/a> already/ - expect(gfm(actual)).to match(expected) - end - - it "should not link with an invalid id" do - # Modify the reference string so it's still parsed, but is invalid - invalid_reference = actual.gsub(/(\d+)$/, "r45") - expect(gfm(invalid_reference)).to eq(invalid_reference) - end - - it "should include a title attribute" do - title = "Issue in JIRA tracker" - expect(gfm(actual)).to match(/title="#{title}"/) - end - - it "should include standard gfm classes" do - expect(gfm(actual)).to match(/class="\s?gfm gfm-issue\s?"/) - end - end - - describe "referencing a merge request" do - let(:object) { merge_request } - let(:reference) { "!#{merge_request.iid}" } - - include_examples 'referenced object' - end - - describe "referencing a snippet" do - let(:object) { snippet } - let(:reference) { "$#{snippet.id}" } - let(:actual) { "Reference to #{reference}" } - let(:expected) { namespace_project_snippet_path(project.namespace, project, object) } - - it "should link using a valid id" do - expect(gfm(actual)).to match(expected) - end - - it "should link with adjacent text" do - # Wrap the reference in parenthesis - expect(gfm(actual.gsub(reference, "(#{reference})"))).to match(expected) - - # Append some text to the end of the reference - expect(gfm(actual.gsub(reference, "#{reference}, right?"))).to match(expected) - end - - it "should keep whitespace intact" do - actual = "Referenced #{reference} already." - expected = /Referenced [^\s]+<\/a> already/ - expect(gfm(actual)).to match(expected) - end - - it "should not link with an invalid id" do - # Modify the reference string so it's still parsed, but is invalid - reference.gsub!(/^(.)(\d+)$/, '\1' + ('\2' * 2)) - expect(gfm(actual)).to eq(actual) - end - - it "should include a title attribute" do - title = "Snippet: #{object.title}" - expect(gfm(actual)).to match(/title="#{title}"/) - end - - it "should include standard gfm classes" do - css = object.class.to_s.underscore - expect(gfm(actual)).to match(/class="\s?gfm gfm-snippet\s?"/) - end - - end - - describe "referencing multiple objects" do - let(:actual) { "!#{merge_request.iid} -> #{commit.id} -> ##{issue.iid}" } - - it "should link to the merge request" do - expected = namespace_project_merge_request_path(project.namespace, project, merge_request) - expect(gfm(actual)).to match(expected) - end - - it "should link to the commit" do - expected = namespace_project_commit_path(project.namespace, project, commit) - expect(gfm(actual)).to match(expected) - end - - it "should link to the issue" do - expected = namespace_project_issue_path(project.namespace, project, issue) - expect(gfm(actual)).to match(expected) - end - end - - describe "emoji" do - it "matches at the start of a string" do - expect(gfm(":+1:")).to match(/ big time/) - end - - it "ignores invalid emoji" do - expect(gfm(":invalid-emoji:")).not_to match(/") - - # Leading commit link - expect(groups[0]).to match(/href="#{commit_path}"/) - expect(groups[0]).to match(/This should finally fix $/) - - # First issue link - expect(groups[1]). - to match(/href="#{namespace_project_issue_path(project.namespace, project, issues[0])}"/) - expect(groups[1]).to match(/##{issues[0].iid}$/) - - # Internal commit link - expect(groups[2]).to match(/href="#{commit_path}"/) - expect(groups[2]).to match(/ and /) - - # Second issue link - expect(groups[3]). - to match(/href="#{namespace_project_issue_path(project.namespace, project, issues[1])}"/) - expect(groups[3]).to match(/##{issues[1].iid}$/) - - # Trailing commit link - expect(groups[4]).to match(/href="#{commit_path}"/) - expect(groups[4]).to match(/ for real$/) - end - - it "should forward HTML options" do - actual = link_to_gfm("Fixed in #{commit.id}", commit_path, class: 'foo') - expect(actual).to have_selector 'a.gfm.gfm-commit.foo' - end - - it "escapes HTML passed in as the body" do - actual = "This is a

    test

    - see ##{issues[0].iid}" - expect(link_to_gfm(actual, commit_path)). - to match('<h1>test</h1>') - end - end - - describe "#markdown" do - it "should handle references in paragraphs" do - actual = "\n\nLorem ipsum dolor sit amet. #{commit.id} Nam pulvinar sapien eget.\n" - expected = namespace_project_commit_path(project.namespace, project, commit) - expect(markdown(actual)).to match(expected) - end - - it "should handle references in headers" do - actual = "\n# Working around ##{issue.iid}\n## Apply !#{merge_request.iid}" - - expect(markdown(actual, no_header_anchors: true)). - to match(%r{Working around ##{issue.iid}}) - expect(markdown(actual, no_header_anchors: true)). - to match(%r{Apply !#{merge_request.iid}}) - end - - it "should add ids and links to headers" do - # Test every rule except nested tags. - text = '..Ab_c-d. e..' - id = 'ab_c-d-e' - expect(markdown("# #{text}")). - to match(%r{

    #{text}

    }) - expect(markdown("# #{text}", {no_header_anchors:true})). - to eq("

    #{text}

    ") - - id = 'link-text' - expect(markdown("# [link text](url) ![img alt](url)")).to match( - %r{

    link text ]*>

    } - ) - end - - it "should handle references in lists" do - project.team << [user, :master] - - actual = "\n* dark: ##{issue.iid}\n* light by @#{member.user.username}" - - expect(markdown(actual)). - to match(%r{
  • dark: ##{issue.iid}
  • }) - expect(markdown(actual)). - to match(%r{
  • light by @#{member.user.username}
  • }) - end - - it "should not link the apostrophe to issue 39" do - project.team << [user, :master] - allow(project.issues). - to receive(:where).with(iid: '39').and_return([issue]) - - actual = "Yes, it is @#{member.user.username}'s task." - expected = /Yes, it is @#{member.user.username}<\/a>'s task/ - expect(markdown(actual)).to match(expected) - end - - it "should not link the apostrophe to issue 39 in code blocks" do - project.team << [user, :master] - allow(project.issues). - to receive(:where).with(iid: '39').and_return([issue]) - - actual = "Yes, `it is @#{member.user.username}'s task.`" - expected = /Yes, it is @gfm\'s task.<\/code>/ - expect(markdown(actual)).to match(expected) - end - - it "should handle references in " do - actual = "Apply _!#{merge_request.iid}_ ASAP" - - expect(markdown(actual)). - to match(%r{Apply !#{merge_request.iid}}) - end - - it "should handle tables" do - actual = %Q{| header 1 | header 2 | -| -------- | -------- | -| cell 1 | cell 2 | -| cell 3 | cell 4 |} - - expect(markdown(actual)).to match(/\Asome code from $#{snippet.id}\nhere too\n\n" - - expect(helper.markdown("\n some code from $#{snippet.id}\n here too\n")). - to eq(target_html) - expect(helper.markdown("\n```\nsome code from $#{snippet.id}\nhere too\n```\n")). - to eq(target_html) - end - - it "should leave inline code untouched" do - expect(markdown("\nDon't use `$#{snippet.id}` here.\n")).to eq( - "

    Don't use $#{snippet.id} here.

    \n" - ) - end - - it "should leave ref-like autolinks untouched" do - expect(markdown("look at http://example.tld/#!#{merge_request.iid}")).to eq("

    look at http://example.tld/#!#{merge_request.iid}

    \n") - end - - it "should leave ref-like href of 'manual' links untouched" do - expect(markdown("why not [inspect !#{merge_request.iid}](http://example.tld/#!#{merge_request.iid})")).to eq("

    why not inspect !#{merge_request.iid}

    \n") - end - - it "should leave ref-like src of images untouched" do - expect(markdown("screen shot: ![some image](http://example.tld/#!#{merge_request.iid})")).to eq("

    screen shot: \"some

    \n") - end - - it "should generate absolute urls for refs" do - expect(markdown("##{issue.iid}")).to include(namespace_project_issue_path(project.namespace, project, issue)) - end - - it "should generate absolute urls for emoji" do - expect(markdown(':smile:')).to( - include(%(src="#{Gitlab.config.gitlab.url}/assets/emoji/#{Emoji.emoji_filename('smile')}.png)) - ) - end - - it "should generate absolute urls for emoji if relative url is present" do - allow(Gitlab.config.gitlab).to receive(:url).and_return('http://localhost/gitlab/root') - expect(markdown(":smile:")).to include("src=\"http://localhost/gitlab/root/assets/emoji/#{Emoji.emoji_filename('smile')}.png") - end - - it "should generate absolute urls for emoji if asset_host is present" do - allow(Gitlab::Application.config).to receive(:asset_host).and_return("https://cdn.example.com") - ActionView::Base.any_instance.stub_chain(:config, :asset_host).and_return("https://cdn.example.com") - expect(markdown(":smile:")).to include("src=\"https://cdn.example.com/assets/emoji/#{Emoji.emoji_filename('smile')}.png") - end - - - it "should handle relative urls for a file in master" do - actual = "[GitLab API doc](doc/api/README.md)\n" - expected = "

    GitLab API doc

    \n" - expect(markdown(actual)).to match(expected) - end - - it "should handle relative urls for a file in master with an anchor" do - actual = "[GitLab API doc](doc/api/README.md#section)\n" - expected = "

    GitLab API doc

    \n" - expect(markdown(actual)).to match(expected) - end - - it "should not handle relative urls for the current file with an anchor" do - actual = "[GitLab API doc](#section)\n" - expected = "

    GitLab API doc

    \n" - expect(markdown(actual)).to match(expected) - end - - it "should handle relative urls for a directory in master" do - actual = "[GitLab API doc](doc/api)\n" - expected = "

    GitLab API doc

    \n" - expect(markdown(actual)).to match(expected) - end - - it "should handle absolute urls" do - actual = "[GitLab](https://www.gitlab.com)\n" - expected = "

    GitLab

    \n" - expect(markdown(actual)).to match(expected) - end - - it "should handle relative urls in reference links for a file in master" do - actual = "[GitLab API doc][GitLab readme]\n [GitLab readme]: doc/api/README.md\n" - expected = "

    GitLab API doc

    \n" - expect(markdown(actual)).to match(expected) - end - - it "should handle relative urls in reference links for a directory in master" do - actual = "[GitLab API doc directory][GitLab readmes]\n [GitLab readmes]: doc/api/\n" - expected = "

    GitLab API doc directory

    \n" - expect(markdown(actual)).to match(expected) - end - - it "should not handle malformed relative urls in reference links for a file in master" do - actual = "[GitLab readme]: doc/api/README.md\n" - expected = "" - expect(markdown(actual)).to match(expected) - end - - it 'should allow whitelisted HTML tags from the user' do - actual = '
    Term
    Definition
    ' - expect(markdown(actual)).to match(actual) - end - - it 'should sanitize tags that are not whitelisted' do - actual = 'no blinks' - expected = 'no inputs allowed no blinks' - expect(markdown(actual)).to match(expected) - expect(markdown(actual)).not_to match('<.textarea>') - expect(markdown(actual)).not_to match('<.blink>') - end - - it 'should allow whitelisted tag attributes from the user' do - actual = 'link text' - expect(markdown(actual)).to match(actual) - end - - it 'should sanitize tag attributes that are not whitelisted' do - actual = 'link text' - expected = 'link text' - expect(markdown(actual)).to match(expected) - end - - it 'should sanitize javascript in attributes' do - actual = %q(link text) - expected = 'link text' - expect(markdown(actual)).to match(expected) - end - end - - describe 'markdown for empty repository' do - before do - @project = empty_project - @repository = empty_project.repository - end - - it "should not touch relative urls" do - actual = "[GitLab API doc][GitLab readme]\n [GitLab readme]: doc/api/README.md\n" - expected = "

    GitLab API doc

    \n" - expect(markdown(actual)).to match(expected) - end - end - - describe "#render_wiki_content" do - before do - @wiki = double('WikiPage') - allow(@wiki).to receive(:content).and_return('wiki content') - end - - it "should use GitLab Flavored Markdown for markdown files" do - allow(@wiki).to receive(:format).and_return(:markdown) - - expect(helper).to receive(:markdown).with('wiki content') - - helper.render_wiki_content(@wiki) - end - - it "should use the Gollum renderer for all other file types" do - allow(@wiki).to receive(:format).and_return(:rdoc) - formatted_content_stub = double('formatted_content') - expect(formatted_content_stub).to receive(:html_safe) - allow(@wiki).to receive(:formatted_content).and_return(formatted_content_stub) - - helper.render_wiki_content(@wiki) - end - end - - describe '#gfm_with_tasks' do - before(:all) do - @source_text_asterisk = </) - expect(nav_link(controller: :bar)).not_to match(/active/) - expect(nav_link(controller: [:foo, :bar])).to match(/active/) - end - - it "performs checks on the current action" do - expect(nav_link(action: :foo)).to match(/
  • /) - expect(nav_link(action: :bar)).not_to match(/active/) - expect(nav_link(action: [:foo, :bar])).to match(/active/) - end - - it "performs checks on both controller and action when both are present" do - expect(nav_link(controller: :bar, action: :foo)).not_to match(/active/) - expect(nav_link(controller: :foo, action: :bar)).not_to match(/active/) - expect(nav_link(controller: :foo, action: :foo)).to match(/active/) - end - - it "accepts a path shorthand" do - expect(nav_link(path: 'foo#bar')).not_to match(/active/) - expect(nav_link(path: 'foo#foo')).to match(/active/) - end - - it "passes extra html options to the list element" do - expect(nav_link(action: :foo, html_options: {class: 'home'})).to match(/
  • /) - expect(nav_link(html_options: {class: 'active'})).to match(/
  • /) - end - end -end diff --git a/spec/helpers/tree_helper_spec.rb b/spec/helpers/tree_helper_spec.rb deleted file mode 100644 index 8271e00f41b24f03669224eaf86cc7d2653efa71..0000000000000000000000000000000000000000 --- a/spec/helpers/tree_helper_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe TreeHelper do - describe 'flatten_tree' do - let(:project) { create(:project) } - - before { - @repository = project.repository - @commit = project.repository.commit("e56497bb") - } - - context "on a directory containing more than one file/directory" do - let(:tree_item) { double(name: "files", path: "files") } - - it "should return the directory name" do - expect(flatten_tree(tree_item)).to match('files') - end - end - - context "on a directory containing only one directory" do - let(:tree_item) { double(name: "foo", path: "foo") } - - it "should return the flattened path" do - expect(flatten_tree(tree_item)).to match('foo/bar') - end - end - end -end diff --git a/spec/javascripts/helpers/.gitkeep b/spec/javascripts/helpers/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/spec/javascripts/stat_graph_contributors_graph_spec.js b/spec/javascripts/stat_graph_contributors_graph_spec.js deleted file mode 100644 index 1090cb7f620724bc757387a0a58cff5283526e3d..0000000000000000000000000000000000000000 --- a/spec/javascripts/stat_graph_contributors_graph_spec.js +++ /dev/null @@ -1,126 +0,0 @@ -describe("ContributorsGraph", function () { - describe("#set_x_domain", function () { - it("set the x_domain", function () { - ContributorsGraph.set_x_domain(20) - expect(ContributorsGraph.prototype.x_domain).toEqual(20) - }) - }) - - describe("#set_y_domain", function () { - it("sets the y_domain", function () { - ContributorsGraph.set_y_domain([{commits: 30}]) - expect(ContributorsGraph.prototype.y_domain).toEqual([0, 30]) - }) - }) - - describe("#init_x_domain", function () { - it("sets the initial x_domain", function () { - ContributorsGraph.init_x_domain([{date: "2013-01-31"}, {date: "2012-01-31"}]) - expect(ContributorsGraph.prototype.x_domain).toEqual(["2012-01-31", "2013-01-31"]) - }) - }) - - describe("#init_y_domain", function () { - it("sets the initial y_domain", function () { - ContributorsGraph.init_y_domain([{commits: 30}]) - expect(ContributorsGraph.prototype.y_domain).toEqual([0, 30]) - }) - }) - - describe("#init_domain", function () { - it("calls init_x_domain and init_y_domain", function () { - spyOn(ContributorsGraph, "init_x_domain") - spyOn(ContributorsGraph, "init_y_domain") - ContributorsGraph.init_domain() - expect(ContributorsGraph.init_x_domain).toHaveBeenCalled() - expect(ContributorsGraph.init_y_domain).toHaveBeenCalled() - }) - }) - - describe("#set_dates", function () { - it("sets the dates", function () { - ContributorsGraph.set_dates("2013-12-01") - expect(ContributorsGraph.prototype.dates).toEqual("2013-12-01") - }) - }) - - describe("#set_x_domain", function () { - it("sets the instance's x domain using the prototype's x_domain", function () { - ContributorsGraph.prototype.x_domain = 20 - var instance = new ContributorsGraph() - instance.x = d3.time.scale().range([0, 100]).clamp(true) - spyOn(instance.x, 'domain') - instance.set_x_domain() - expect(instance.x.domain).toHaveBeenCalledWith(20) - }) - }) - - describe("#set_y_domain", function () { - it("sets the instance's y domain using the prototype's y_domain", function () { - ContributorsGraph.prototype.y_domain = 30 - var instance = new ContributorsGraph() - instance.y = d3.scale.linear().range([100, 0]).nice() - spyOn(instance.y, 'domain') - instance.set_y_domain() - expect(instance.y.domain).toHaveBeenCalledWith(30) - }) - }) - - describe("#set_domain", function () { - it("calls set_x_domain and set_y_domain", function () { - var instance = new ContributorsGraph() - spyOn(instance, 'set_x_domain') - spyOn(instance, 'set_y_domain') - instance.set_domain() - expect(instance.set_x_domain).toHaveBeenCalled() - expect(instance.set_y_domain).toHaveBeenCalled() - }) - }) - - describe("#set_data", function () { - it("sets the data", function () { - var instance = new ContributorsGraph() - instance.set_data("20") - expect(instance.data).toEqual("20") - }) - }) -}) - -describe("ContributorsMasterGraph", function () { - - // TODO: fix or remove - //describe("#process_dates", function () { - //it("gets and parses dates", function () { - //var graph = new ContributorsMasterGraph() - //var data = 'random data here' - //spyOn(graph, 'parse_dates') - //spyOn(graph, 'get_dates').andReturn("get") - //spyOn(ContributorsGraph,'set_dates').andCallThrough() - //graph.process_dates(data) - //expect(graph.parse_dates).toHaveBeenCalledWith(data) - //expect(graph.get_dates).toHaveBeenCalledWith(data) - //expect(ContributorsGraph.set_dates).toHaveBeenCalledWith("get") - //}) - //}) - - describe("#get_dates", function () { - it("plucks the date field from data collection", function () { - var graph = new ContributorsMasterGraph() - var data = [{date: "2013-01-01"}, {date: "2012-12-15"}] - expect(graph.get_dates(data)).toEqual(["2013-01-01", "2012-12-15"]) - }) - }) - - describe("#parse_dates", function () { - it("parses the dates", function () { - var graph = new ContributorsMasterGraph() - var parseDate = d3.time.format("%Y-%m-%d").parse - var data = [{date: "2013-01-01"}, {date: "2012-12-15"}] - var correct = [{date: parseDate(data[0].date)}, {date: parseDate(data[1].date)}] - graph.parse_dates(data) - expect(data).toEqual(correct) - }) - }) - - -}) diff --git a/spec/javascripts/stat_graph_contributors_util_spec.js b/spec/javascripts/stat_graph_contributors_util_spec.js deleted file mode 100644 index 9c1b588861d98861651533be5b6bf99fd400ea69..0000000000000000000000000000000000000000 --- a/spec/javascripts/stat_graph_contributors_util_spec.js +++ /dev/null @@ -1,208 +0,0 @@ -describe("ContributorsStatGraphUtil", function () { - - describe("#parse_log", function () { - it("returns a correctly parsed log", function () { - var fake_log = [ - {author_email: "karlo@email.com", author_name: "Karlo Soriano", date: "2013-05-09", additions: 471}, - {author_email: "dzaporozhets@email.com", author_name: "Dmitriy Zaporozhets", date: "2013-05-08", additions: 6, deletions: 1}, - {author_email: "dzaporozhets@email.com", author_name: "Dmitriy Zaporozhets", date: "2013-05-08", additions: 19, deletions: 3}, - {author_email: "dzaporozhets@email.com", author_name: "Dmitriy Zaporozhets", date: "2013-05-08", additions: 29, deletions: 3}] - - var correct_parsed_log = { - total: [ - {date: "2013-05-09", additions: 471, deletions: 0, commits: 1}, - {date: "2013-05-08", additions: 54, deletions: 7, commits: 3}], - by_author: - [ - { - author_name: "Karlo Soriano", author_email: "karlo@email.com", - "2013-05-09": {date: "2013-05-09", additions: 471, deletions: 0, commits: 1} - }, - { - author_name: "Dmitriy Zaporozhets",author_email: "dzaporozhets@email.com", - "2013-05-08": {date: "2013-05-08", additions: 54, deletions: 7, commits: 3} - } - ] - } - expect(ContributorsStatGraphUtil.parse_log(fake_log)).toEqual(correct_parsed_log) - }) - }) - - describe("#store_data", function () { - - var fake_entry = {author: "Karlo Soriano", date: "2013-05-09", additions: 471} - var fake_total = {} - var fake_by_author = {} - - it("calls #store_commits", function () { - spyOn(ContributorsStatGraphUtil, 'store_commits') - ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author) - expect(ContributorsStatGraphUtil.store_commits).toHaveBeenCalled() - }) - - it("calls #store_additions", function () { - spyOn(ContributorsStatGraphUtil, 'store_additions') - ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author) - expect(ContributorsStatGraphUtil.store_additions).toHaveBeenCalled() - }) - - it("calls #store_deletions", function () { - spyOn(ContributorsStatGraphUtil, 'store_deletions') - ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author) - expect(ContributorsStatGraphUtil.store_deletions).toHaveBeenCalled() - }) - - }) - - // TODO: fix or remove - //describe("#store_commits", function () { - //var fake_total = "fake_total" - //var fake_by_author = "fake_by_author" - - //it("calls #add twice with arguments fake_total and fake_by_author respectively", function () { - //spyOn(ContributorsStatGraphUtil, 'add') - //ContributorsStatGraphUtil.store_commits(fake_total, fake_by_author) - //expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "commits", 1], ["fake_by_author", "commits", 1]]) - //}) - //}) - - describe("#add", function () { - it("adds 1 to current test_field in collection", function () { - var fake_collection = {test_field: 10} - ContributorsStatGraphUtil.add(fake_collection, "test_field", 1) - expect(fake_collection.test_field).toEqual(11) - }) - - it("inits and adds 1 if test_field in collection is not defined", function () { - var fake_collection = {} - ContributorsStatGraphUtil.add(fake_collection, "test_field", 1) - expect(fake_collection.test_field).toEqual(1) - }) - }) - - // TODO: fix or remove - //describe("#store_additions", function () { - //var fake_entry = {additions: 10} - //var fake_total= "fake_total" - //var fake_by_author = "fake_by_author" - //it("calls #add twice with arguments fake_total and fake_by_author respectively", function () { - //spyOn(ContributorsStatGraphUtil, 'add') - //ContributorsStatGraphUtil.store_additions(fake_entry, fake_total, fake_by_author) - //expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "additions", 10], ["fake_by_author", "additions", 10]]) - //}) - //}) - - // TODO: fix or remove - //describe("#store_deletions", function () { - //var fake_entry = {deletions: 10} - //var fake_total= "fake_total" - //var fake_by_author = "fake_by_author" - //it("calls #add twice with arguments fake_total and fake_by_author respectively", function () { - //spyOn(ContributorsStatGraphUtil, 'add') - //ContributorsStatGraphUtil.store_deletions(fake_entry, fake_total, fake_by_author) - //expect(ContributorsStatGraphUtil.add.argsForCall).toEqual([["fake_total", "deletions", 10], ["fake_by_author", "deletions", 10]]) - //}) - //}) - - describe("#add_date", function () { - it("adds a date field to the collection", function () { - var fake_date = "2013-10-02" - var fake_collection = {} - ContributorsStatGraphUtil.add_date(fake_date, fake_collection) - expect(fake_collection[fake_date].date).toEqual("2013-10-02") - }) - }) - - describe("#add_author", function () { - it("adds an author field to the collection", function () { - var fake_author = { author_name: "Author", author_email: 'fake@email.com' } - var fake_collection = {} - ContributorsStatGraphUtil.add_author(fake_author, fake_collection) - expect(fake_collection[fake_author.author_name].author_name).toEqual("Author") - }) - }) - - describe("#get_total_data", function () { - it("returns the collection sorted via specified field", function () { - var fake_parsed_log = { - total: [{date: "2013-05-09", additions: 471, deletions: 0, commits: 1}, - {date: "2013-05-08", additions: 54, deletions: 7, commits: 3}], - by_author:[ - { - author: "Karlo Soriano", - "2013-05-09": {date: "2013-05-09", additions: 471, deletions: 0, commits: 1} - }, - { - author: "Dmitriy Zaporozhets", - "2013-05-08": {date: "2013-05-08", additions: 54, deletions: 7, commits: 3} - } - ]}; - var correct_total_data = [{date: "2013-05-08", commits: 3}, - {date: "2013-05-09", commits: 1}]; - expect(ContributorsStatGraphUtil.get_total_data(fake_parsed_log, "commits")).toEqual(correct_total_data) - }) - }) - - describe("#pick_field", function () { - it("returns the collection with only the specified field and date", function () { - var fake_parsed_log_total = [{date: "2013-05-09", additions: 471, deletions: 0, commits: 1}, - {date: "2013-05-08", additions: 54, deletions: 7, commits: 3}]; - ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, "commits") - var correct_pick_field_data = [{date: "2013-05-09", commits: 1},{date: "2013-05-08", commits: 3}]; - expect(ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, "commits")).toEqual(correct_pick_field_data) - }) - }) - - describe("#get_author_data", function () { - it("returns the log by author sorted by specified field", function () { - var fake_parsed_log = { - total: [ - {date: "2013-05-09", additions: 471, deletions: 0, commits: 1}, - {date: "2013-05-08", additions: 54, deletions: 7, commits: 3} - ], - by_author: [ - { - author_name: "Karlo Soriano", author_email: "karlo@email.com", - "2013-05-09": {date: "2013-05-09", additions: 471, deletions: 0, commits: 1} - }, - { - author_name: "Dmitriy Zaporozhets", author_email: "dzaporozhets@email.com", - "2013-05-08": {date: "2013-05-08", additions: 54, deletions: 7, commits: 3} - } - ] - } - var correct_author_data = [ - {author_name:"Dmitriy Zaporozhets",author_email:"dzaporozhets@email.com",dates:{"2013-05-08":3},deletions:7,additions:54,"commits":3}, - {author_name:"Karlo Soriano",author_email:"karlo@email.com",dates:{"2013-05-09":1},deletions:0,additions:471,commits:1} - ] - expect(ContributorsStatGraphUtil.get_author_data(fake_parsed_log, "commits")).toEqual(correct_author_data) - }) - }) - - describe("#parse_log_entry", function () { - it("adds the corresponding info from the log entry to the author", function () { - var fake_log_entry = { author_name: "Karlo Soriano", author_email: "karlo@email.com", - "2013-05-09": {date: "2013-05-09", additions: 471, deletions: 0, commits: 1} - } - var correct_parsed_log = {author_name:"Karlo Soriano",author_email:"karlo@email.com",dates:{"2013-05-09":1},deletions:0,additions:471,commits:1} - expect(ContributorsStatGraphUtil.parse_log_entry(fake_log_entry, 'commits', null)).toEqual(correct_parsed_log) - }) - }) - - describe("#in_range", function () { - var date = "2013-05-09" - it("returns true if date_range is null", function () { - expect(ContributorsStatGraphUtil.in_range(date, null)).toEqual(true) - }) - it("returns true if date is in range", function () { - var date_range = [new Date("2013-01-01"), new Date("2013-12-12")] - expect(ContributorsStatGraphUtil.in_range(date, date_range)).toEqual(true) - }) - it("returns false if date is not in range", function () { - var date_range = [new Date("1999-12-01"), new Date("2000-12-01")] - expect(ContributorsStatGraphUtil.in_range(date, date_range)).toEqual(false) - }) - }) - - -}) diff --git a/spec/javascripts/stat_graph_spec.js b/spec/javascripts/stat_graph_spec.js deleted file mode 100644 index b589af34610bb8daacbeafecdfe0bf7d57a57187..0000000000000000000000000000000000000000 --- a/spec/javascripts/stat_graph_spec.js +++ /dev/null @@ -1,17 +0,0 @@ -describe("StatGraph", function () { - - describe("#get_log", function () { - it("returns log", function () { - StatGraph.log = "test"; - expect(StatGraph.get_log()).toBe("test"); - }); - }); - - describe("#set_log", function () { - it("sets the log", function () { - StatGraph.set_log("test"); - expect(StatGraph.log).toBe("test"); - }) - }) - -}); diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml deleted file mode 100644 index 9bfa261a356ac0707d3bc959ba99e99b381bf68e..0000000000000000000000000000000000000000 --- a/spec/javascripts/support/jasmine.yml +++ /dev/null @@ -1,76 +0,0 @@ -# src_files -# -# Return an array of filepaths relative to src_dir to include before jasmine specs. -# Default: [] -# -# EXAMPLE: -# -# src_files: -# - lib/source1.js -# - lib/source2.js -# - dist/**/*.js -# -src_files: - - assets/application.js - -# stylesheets -# -# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs. -# Default: [] -# -# EXAMPLE: -# -# stylesheets: -# - css/style.css -# - stylesheets/*.css -# -stylesheets: - - stylesheets/**/*.css - -# helpers -# -# Return an array of filepaths relative to spec_dir to include before jasmine specs. -# Default: ["helpers/**/*.js"] -# -# EXAMPLE: -# -# helpers: -# - helpers/**/*.js -# -helpers: - - helpers/**/*.js - -# spec_files -# -# Return an array of filepaths relative to spec_dir to include. -# Default: ["**/*[sS]pec.js"] -# -# EXAMPLE: -# -# spec_files: -# - **/*[sS]pec.js -# -spec_files: - - '**/*[sS]pec.js' - -# src_dir -# -# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank. -# Default: project root -# -# EXAMPLE: -# -# src_dir: public -# -src_dir: - -# spec_dir -# -# Spec directory path. Your spec_files must be returned relative to this path. -# Default: spec/javascripts -# -# EXAMPLE: -# -# spec_dir: spec/javascripts -# -spec_dir: spec/javascripts diff --git a/spec/javascripts/support/jasmine_helper.rb b/spec/javascripts/support/jasmine_helper.rb deleted file mode 100644 index b4919802afe405cd727abf936f9b074792bf3d97..0000000000000000000000000000000000000000 --- a/spec/javascripts/support/jasmine_helper.rb +++ /dev/null @@ -1,11 +0,0 @@ -#Use this file to set/override Jasmine configuration options -#You can remove it if you don't need it. -#This file is loaded *after* jasmine.yml is interpreted. -# -#Example: using a different boot file. -#Jasmine.configure do |config| -# config.boot_dir = '/absolute/path/to/boot_dir' -# config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] } -#end -# - diff --git a/spec/lib/disable_email_interceptor_spec.rb b/spec/lib/disable_email_interceptor_spec.rb deleted file mode 100644 index 06d5450688baf556d40bec2390f8f93878e6690e..0000000000000000000000000000000000000000 --- a/spec/lib/disable_email_interceptor_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe DisableEmailInterceptor do - before do - ActionMailer::Base.register_interceptor(DisableEmailInterceptor) - end - - it 'should not send emails' do - allow(Gitlab.config.gitlab).to receive(:email_enabled).and_return(false) - expect { - deliver_mail - }.not_to change(ActionMailer::Base.deliveries, :count) - end - - after do - # Removing interceptor from the list because unregister_interceptor is - # implemented in later version of mail gem - # See: https://github.com/mikel/mail/pull/705 - Mail.class_variable_set(:@@delivery_interceptors, []) - end - - def deliver_mail - key = create :personal_key - Notify.new_ssh_key_email(key.id) - end -end diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb deleted file mode 100644 index ac602eac154bce6b5992dfe8a9149ff445fe2130..0000000000000000000000000000000000000000 --- a/spec/lib/extracts_path_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -require 'spec_helper' - -describe ExtractsPath do - include ExtractsPath - - let(:project) { double('project') } - - before do - @project = project - project.stub(repository: double(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0'])) - project.stub(path_with_namespace: 'gitlab/gitlab-ci') - end - - describe '#extract_ref' do - it "returns an empty pair when no @project is set" do - @project = nil - expect(extract_ref('master/CHANGELOG')).to eq(['', '']) - end - - context "without a path" do - it "extracts a valid branch" do - expect(extract_ref('master')).to eq(['master', '']) - end - - it "extracts a valid tag" do - expect(extract_ref('v2.0.0')).to eq(['v2.0.0', '']) - end - - it "extracts a valid commit ref without a path" do - expect(extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062')).to eq( - ['f4b14494ef6abf3d144c28e4af0c20143383e062', ''] - ) - end - - it "falls back to a primitive split for an invalid ref" do - expect(extract_ref('stable')).to eq(['stable', '']) - end - end - - context "with a path" do - it "extracts a valid branch" do - expect(extract_ref('foo/bar/baz/CHANGELOG')).to eq(['foo/bar/baz', 'CHANGELOG']) - end - - it "extracts a valid tag" do - expect(extract_ref('v2.0.0/CHANGELOG')).to eq(['v2.0.0', 'CHANGELOG']) - end - - it "extracts a valid commit SHA" do - expect(extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG')).to eq( - ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG'] - ) - end - - it "falls back to a primitive split for an invalid ref" do - expect(extract_ref('stable/CHANGELOG')).to eq(['stable', 'CHANGELOG']) - end - end - end -end diff --git a/spec/lib/file_size_validator_spec.rb b/spec/lib/file_size_validator_spec.rb deleted file mode 100644 index 5c89c8547142462c7d1251138df3a1e74cbcd152..0000000000000000000000000000000000000000 --- a/spec/lib/file_size_validator_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'spec_helper' - -describe 'Gitlab::FileSizeValidatorSpec' do - let(:validator) { FileSizeValidator.new(options) } - let(:attachment) { AttachmentUploader.new } - let(:note) { create(:note) } - - describe 'options uses an integer' do - let(:options) { { maximum: 10, attributes: { attachment: attachment } } } - - it 'attachment exceeds maximum limit' do - allow(attachment).to receive(:size) { 100 } - validator.validate_each(note, :attachment, attachment) - expect(note.errors).to have_key(:attachment) - end - - it 'attachment under maximum limit' do - allow(attachment).to receive(:size) { 1 } - validator.validate_each(note, :attachment, attachment) - expect(note.errors).not_to have_key(:attachment) - end - end - - describe 'options uses a symbol' do - let(:options) { { maximum: :test, - attributes: { attachment: attachment } } } - before do - allow(note).to receive(:test) { 10 } - end - - it 'attachment exceeds maximum limit' do - allow(attachment).to receive(:size) { 100 } - validator.validate_each(note, :attachment, attachment) - expect(note.errors).to have_key(:attachment) - end - - it 'attachment under maximum limit' do - allow(attachment).to receive(:size) { 1 } - validator.validate_each(note, :attachment, attachment) - expect(note.errors).not_to have_key(:attachment) - end - end -end diff --git a/spec/lib/git_ref_validator_spec.rb b/spec/lib/git_ref_validator_spec.rb deleted file mode 100644 index 4633b6f3934b9ddf7e00c1cf3ea35e10d3da9f57..0000000000000000000000000000000000000000 --- a/spec/lib/git_ref_validator_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GitRefValidator do - it { expect(Gitlab::GitRefValidator.validate('feature/new')).to be_truthy } - it { expect(Gitlab::GitRefValidator.validate('implement_@all')).to be_truthy } - it { expect(Gitlab::GitRefValidator.validate('my_new_feature')).to be_truthy } - it { expect(Gitlab::GitRefValidator.validate('#1')).to be_truthy } - it { expect(Gitlab::GitRefValidator.validate('feature/~new/')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature/^new/')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature/:new/')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature/?new/')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature/*new/')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature/[new/')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature/new/')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature/new.')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature\@{')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature\new')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature//new')).to be_falsey } - it { expect(Gitlab::GitRefValidator.validate('feature new')).to be_falsey } -end diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb deleted file mode 100644 index 95fc7e16a1102b8838a0395af3eb6fbd54352cd8..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/auth_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Auth do - let(:gl_auth) { Gitlab::Auth.new } - - describe :find do - let!(:user) do - create(:user, - username: username, - password: password, - password_confirmation: password) - end - let(:username) { 'John' } # username isn't lowercase, test this - let(:password) { 'my-secret' } - - it "should find user by valid login/password" do - expect( gl_auth.find(username, password) ).to eql user - end - - it 'should find user by valid email/password with case-insensitive email' do - expect(gl_auth.find(user.email.upcase, password)).to eql user - end - - it 'should find user by valid username/password with case-insensitive username' do - expect(gl_auth.find(username.upcase, password)).to eql user - end - - it "should not find user with invalid password" do - password = 'wrong' - expect( gl_auth.find(username, password) ).to_not eql user - end - - it "should not find user with invalid login" do - user = 'wrong' - expect( gl_auth.find(username, password) ).to_not eql user - end - - context "with ldap enabled" do - before { Gitlab::LDAP::Config.stub(enabled?: true) } - - it "tries to autheticate with db before ldap" do - expect(Gitlab::LDAP::Authentication).not_to receive(:login) - - gl_auth.find(username, password) - end - - it "uses ldap as fallback to for authentication" do - expect(Gitlab::LDAP::Authentication).to receive(:login) - - gl_auth.find('ldap_user', 'password') - end - end - end -end diff --git a/spec/lib/gitlab/backend/grack_auth_spec.rb b/spec/lib/gitlab/backend/grack_auth_spec.rb deleted file mode 100644 index d0aad54f677fa11e79a95c897a2689e91ae4de44..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/backend/grack_auth_spec.rb +++ /dev/null @@ -1,196 +0,0 @@ -require "spec_helper" - -describe Grack::Auth do - let(:user) { create(:user) } - let(:project) { create(:project) } - - let(:app) { lambda { |env| [200, {}, "Success!"] } } - let!(:auth) { Grack::Auth.new(app) } - let(:env) { - { - "rack.input" => "", - "REQUEST_METHOD" => "GET", - "QUERY_STRING" => "service=git-upload-pack" - } - } - let(:status) { auth.call(env).first } - - describe "#call" do - context "when the project doesn't exist" do - before do - env["PATH_INFO"] = "doesnt/exist.git" - end - - context "when no authentication is provided" do - it "responds with status 401" do - expect(status).to eq(401) - end - end - - context "when username and password are provided" do - context "when authentication fails" do - before do - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, "nope") - end - - it "responds with status 401" do - expect(status).to eq(401) - end - end - - context "when authentication succeeds" do - before do - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password) - end - - it "responds with status 404" do - expect(status).to eq(404) - end - end - end - end - - context "when the project exists" do - before do - env["PATH_INFO"] = project.path_with_namespace + ".git" - end - - context "when the project is public" do - before do - project.update_attribute(:visibility_level, Project::PUBLIC) - end - - it "responds with status 200" do - expect(status).to eq(200) - end - end - - context "when the project is private" do - before do - project.update_attribute(:visibility_level, Project::PRIVATE) - end - - context "when no authentication is provided" do - it "responds with status 401" do - expect(status).to eq(401) - end - end - - context "when username and password are provided" do - context "when authentication fails" do - before do - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, "nope") - end - - it "responds with status 401" do - expect(status).to eq(401) - end - - context "when the user is IP banned" do - before do - expect(Rack::Attack::Allow2Ban).to receive(:filter).and_return(true) - allow_any_instance_of(Rack::Request).to receive(:ip).and_return('1.2.3.4') - end - - it "responds with status 401" do - expect(status).to eq(401) - end - end - end - - context "when authentication succeeds" do - before do - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password) - end - - context "when the user has access to the project" do - before do - project.team << [user, :master] - end - - context "when the user is blocked" do - before do - user.block - project.team << [user, :master] - end - - it "responds with status 404" do - expect(status).to eq(404) - end - end - - context "when the user isn't blocked" do - before do - expect(Rack::Attack::Allow2Ban).to receive(:reset) - end - - it "responds with status 200" do - expect(status).to eq(200) - end - end - - context "when blank password attempts follow a valid login" do - let(:options) { Gitlab.config.rack_attack.git_basic_auth } - let(:maxretry) { options[:maxretry] - 1 } - let(:ip) { '1.2.3.4' } - - before do - allow_any_instance_of(Rack::Request).to receive(:ip).and_return(ip) - Rack::Attack::Allow2Ban.reset(ip, options) - end - - after do - Rack::Attack::Allow2Ban.reset(ip, options) - end - - def attempt_login(include_password) - password = include_password ? user.password : "" - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, password) - Grack::Auth.new(app) - auth.call(env).first - end - - it "repeated attempts followed by successful attempt" do - for n in 0..maxretry do - expect(attempt_login(false)).to eq(401) - end - - expect(attempt_login(true)).to eq(200) - expect(Rack::Attack::Allow2Ban.send(:banned?, ip)).to eq(nil) - - for n in 0..maxretry do - expect(attempt_login(false)).to eq(401) - end - end - end - end - - context "when the user doesn't have access to the project" do - it "responds with status 404" do - expect(status).to eq(404) - end - end - end - end - - context "when a gitlab ci token is provided" do - let(:token) { "123" } - - before do - gitlab_ci_service = project.build_gitlab_ci_service - gitlab_ci_service.active = true - gitlab_ci_service.token = token - gitlab_ci_service.project_url = "http://google.com" - gitlab_ci_service.save - - env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials("gitlab-ci-token", token) - end - - it "responds with status 200" do - expect(status).to eq(200) - end - end - end - end - end -end diff --git a/spec/lib/gitlab/backend/rack_attack_helpers_spec.rb b/spec/lib/gitlab/backend/rack_attack_helpers_spec.rb deleted file mode 100644 index 2ac496fd669a62cb3b48b0dd9377d580a6df8bbf..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/backend/rack_attack_helpers_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require "spec_helper" - -describe 'RackAttackHelpers' do - describe 'reset' do - let(:discriminator) { 'test-key'} - let(:maxretry) { 5 } - let(:period) { 1.minute } - let(:options) { { findtime: period, bantime: 60, maxretry: maxretry } } - - def do_filter - for i in 1..maxretry - 1 do - status = Rack::Attack::Allow2Ban.filter(discriminator, options) { true } - expect(status).to eq(false) - end - end - - def do_reset - Rack::Attack::Allow2Ban.reset(discriminator, options) - end - - before do - do_reset - end - - after do - do_reset - end - - it 'user is not banned after n - 1 retries' do - do_filter - do_reset - do_filter - end - end -end diff --git a/spec/lib/gitlab/backend/shell_spec.rb b/spec/lib/gitlab/backend/shell_spec.rb deleted file mode 100644 index 27279465c1aece0b6f00bccfac48a57520386e9c..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/backend/shell_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Shell do - let(:project) { double('Project', id: 7, path: 'diaspora') } - let(:gitlab_shell) { Gitlab::Shell.new } - - before do - Project.stub(find: project) - end - - it { is_expected.to respond_to :add_key } - it { is_expected.to respond_to :remove_key } - it { is_expected.to respond_to :add_repository } - it { is_expected.to respond_to :remove_repository } - it { is_expected.to respond_to :fork_repository } - - it { expect(gitlab_shell.url_to_repo('diaspora')).to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + "diaspora.git") } -end diff --git a/spec/lib/gitlab/bitbucket_import/client_spec.rb b/spec/lib/gitlab/bitbucket_import/client_spec.rb deleted file mode 100644 index dd450e9967b338f0b0ffb2929fb1afd1749272c2..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/bitbucket_import/client_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'spec_helper' - -describe Gitlab::BitbucketImport::Client do - let(:token) { '123456' } - let(:secret) { 'secret' } - let(:client) { Gitlab::BitbucketImport::Client.new(token, secret) } - - before do - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "bitbucket") - end - - it 'all OAuth client options are symbols' do - client.consumer.options.keys.each do |key| - expect(key).to be_kind_of(Symbol) - end - end -end diff --git a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb b/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb deleted file mode 100644 index 0ec6a43f681c6eb93636eea8c2af093d79fcd518..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/bitbucket_import/project_creator_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe Gitlab::BitbucketImport::ProjectCreator do - let(:user) { create(:user, bitbucket_access_token: "asdffg", bitbucket_access_token_secret: "sekret") } - let(:repo) { { - name: 'Vim', - slug: 'vim', - is_private: true, - owner: "asd"}.with_indifferent_access - } - let(:namespace){ create(:group, owner: user) } - - before do - namespace.add_owner(user) - end - - it 'creates project' do - allow_any_instance_of(Project).to receive(:add_import_job) - - project_creator = Gitlab::BitbucketImport::ProjectCreator.new(repo, namespace, user) - project = project_creator.execute - - expect(project.import_url).to eq("ssh://git@bitbucket.org/asd/vim.git") - expect(project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) - end -end diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb deleted file mode 100644 index cb7b0fbb8902ae4b9504de7323bfe5312b879d56..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/closing_issue_extractor_spec.rb +++ /dev/null @@ -1,176 +0,0 @@ -require 'spec_helper' - -describe Gitlab::ClosingIssueExtractor do - let(:project) { create(:project) } - let(:issue) { create(:issue, project: project) } - let(:iid1) { issue.iid } - - subject { described_class.new(project, project.creator) } - - describe "#closed_by_message" do - context 'with a single reference' do - it do - message = "Awesome commit (Closes ##{iid1})" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Awesome commit (closes ##{iid1})" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Closed ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "closed ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Closing ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "closing ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Close ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "close ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Awesome commit (Fixes ##{iid1})" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Awesome commit (fixes ##{iid1})" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Fixed ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "fixed ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Fixing ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "fixing ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Fix ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "fix ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Awesome commit (Resolves ##{iid1})" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Awesome commit (resolves ##{iid1})" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Resolved ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "resolved ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Resolving ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "resolving ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "Resolve ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - - it do - message = "resolve ##{iid1}" - expect(subject.closed_by_message(message)).to eq([issue]) - end - end - - context 'with multiple references' do - let(:other_issue) { create(:issue, project: project) } - let(:third_issue) { create(:issue, project: project) } - let(:iid2) { other_issue.iid } - let(:iid3) { third_issue.iid } - - it 'fetches issues in single line message' do - message = "Closes ##{iid1} and fix ##{iid2}" - - expect(subject.closed_by_message(message)). - to eq([issue, other_issue]) - end - - it 'fetches comma-separated issues references in single line message' do - message = "Closes ##{iid1}, closes ##{iid2}" - - expect(subject.closed_by_message(message)). - to eq([issue, other_issue]) - end - - it 'fetches comma-separated issues numbers in single line message' do - message = "Closes ##{iid1}, ##{iid2} and ##{iid3}" - - expect(subject.closed_by_message(message)). - to eq([issue, other_issue, third_issue]) - end - - it 'fetches issues in multi-line message' do - message = "Awesome commit (closes ##{iid1})\nAlso fixes ##{iid2}" - - expect(subject.closed_by_message(message)). - to eq([issue, other_issue]) - end - - it 'fetches issues in hybrid message' do - message = "Awesome commit (closes ##{iid1})\n"\ - "Also fixing issues ##{iid2}, ##{iid3} and #4" - - expect(subject.closed_by_message(message)). - to eq([issue, other_issue, third_issue]) - end - end - end -end diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb deleted file mode 100644 index 40eb45e37cafd9348b73200e5893312c01889672..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/diff/file_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Diff::File do - include RepoHelpers - - let(:project) { create(:project) } - let(:commit) { project.repository.commit(sample_commit.id) } - let(:diff) { commit.diffs.first } - let(:diff_file) { Gitlab::Diff::File.new(diff) } - - describe :diff_lines do - let(:diff_lines) { diff_file.diff_lines } - - it { expect(diff_lines.size).to eq(30) } - it { expect(diff_lines.first).to be_kind_of(Gitlab::Diff::Line) } - end - - describe :mode_changed? do - it { expect(diff_file.mode_changed?).to be_falsey } - end -end diff --git a/spec/lib/gitlab/diff/parser_spec.rb b/spec/lib/gitlab/diff/parser_spec.rb deleted file mode 100644 index 918f6d0ead4f11b408d30f4fb06918558cdcdd30..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/diff/parser_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Diff::Parser do - include RepoHelpers - - let(:project) { create(:project) } - let(:commit) { project.repository.commit(sample_commit.id) } - let(:diff) { commit.diffs.first } - let(:parser) { Gitlab::Diff::Parser.new } - - describe :parse do - let(:diff) do - < path } -- options = { chdir: path } -+ -+ vars = { -+ "PWD" => path -+ } -+ -+ options = { -+ chdir: path -+ } - - unless File.directory?(path) - FileUtils.mkdir_p(path) -@@ -19,6 +25,7 @@ module Popen - - @cmd_output = "" - @cmd_status = 0 -+ - Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr| - @cmd_output << stdout.read - @cmd_output << stderr.read -eos - end - - before do - @lines = parser.parse(diff.lines) - end - - it { expect(@lines.size).to eq(30) } - - describe 'lines' do - describe 'first line' do - let(:line) { @lines.first } - - it { expect(line.type).to eq('match') } - it { expect(line.old_pos).to eq(6) } - it { expect(line.new_pos).to eq(6) } - it { expect(line.text).to eq('@@ -6,12 +6,18 @@ module Popen') } - end - - describe 'removal line' do - let(:line) { @lines[10] } - - it { expect(line.type).to eq('old') } - it { expect(line.old_pos).to eq(14) } - it { expect(line.new_pos).to eq(13) } - it { expect(line.text).to eq('- options = { chdir: path }') } - end - - describe 'addition line' do - let(:line) { @lines[16] } - - it { expect(line.type).to eq('new') } - it { expect(line.old_pos).to eq(15) } - it { expect(line.new_pos).to eq(18) } - it { expect(line.text).to eq('+ options = {') } - end - - describe 'unchanged line' do - let(:line) { @lines.last } - - it { expect(line.type).to eq(nil) } - it { expect(line.old_pos).to eq(24) } - it { expect(line.new_pos).to eq(31) } - it { expect(line.text).to eq(' @cmd_output << stderr.read') } - end - end - end -end diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb deleted file mode 100644 index 39be9d646442c761595f5ef28952d97315558515..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/git_access_spec.rb +++ /dev/null @@ -1,235 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GitAccess do - let(:access) { Gitlab::GitAccess.new(actor, project) } - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:actor) { user } - - describe 'can_push_to_branch?' do - describe 'push to none protected branch' do - it "returns true if user is a master" do - project.team << [user, :master] - expect(access.can_push_to_branch?("random_branch")).to be_truthy - end - - it "returns true if user is a developer" do - project.team << [user, :developer] - expect(access.can_push_to_branch?("random_branch")).to be_truthy - end - - it "returns false if user is a reporter" do - project.team << [user, :reporter] - expect(access.can_push_to_branch?("random_branch")).to be_falsey - end - end - - describe 'push to protected branch' do - before do - @branch = create :protected_branch, project: project - end - - it "returns true if user is a master" do - project.team << [user, :master] - expect(access.can_push_to_branch?(@branch.name)).to be_truthy - end - - it "returns false if user is a developer" do - project.team << [user, :developer] - expect(access.can_push_to_branch?(@branch.name)).to be_falsey - end - - it "returns false if user is a reporter" do - project.team << [user, :reporter] - expect(access.can_push_to_branch?(@branch.name)).to be_falsey - end - end - - describe 'push to protected branch if allowed for developers' do - before do - @branch = create :protected_branch, project: project, developers_can_push: true - end - - it "returns true if user is a master" do - project.team << [user, :master] - expect(access.can_push_to_branch?(@branch.name)).to be_truthy - end - - it "returns true if user is a developer" do - project.team << [user, :developer] - expect(access.can_push_to_branch?(@branch.name)).to be_truthy - end - - it "returns false if user is a reporter" do - project.team << [user, :reporter] - expect(access.can_push_to_branch?(@branch.name)).to be_falsey - end - end - - end - - describe 'download_access_check' do - describe 'master permissions' do - before { project.team << [user, :master] } - - context 'pull code' do - subject { access.download_access_check } - - it { expect(subject.allowed?).to be_truthy } - end - end - - describe 'guest permissions' do - before { project.team << [user, :guest] } - - context 'pull code' do - subject { access.download_access_check } - - it { expect(subject.allowed?).to be_falsey } - end - end - - describe 'blocked user' do - before do - project.team << [user, :master] - user.block - end - - context 'pull code' do - subject { access.download_access_check } - - it { expect(subject.allowed?).to be_falsey } - end - end - - describe 'without acccess to project' do - context 'pull code' do - subject { access.download_access_check } - - it { expect(subject.allowed?).to be_falsey } - end - end - - describe 'deploy key permissions' do - let(:key) { create(:deploy_key) } - let(:actor) { key } - - context 'pull code' do - context 'allowed' do - before { key.projects << project } - subject { access.download_access_check } - - it { expect(subject.allowed?).to be_truthy } - end - - context 'denied' do - subject { access.download_access_check } - - it { expect(subject.allowed?).to be_falsey } - end - end - end - end - - describe 'push_access_check' do - def protect_feature_branch - create(:protected_branch, name: 'feature', project: project) - end - - def changes - { - push_new_branch: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/heads/wow", - push_master: '6f6d7e7ed 570e7b2ab refs/heads/master', - push_protected_branch: '6f6d7e7ed 570e7b2ab refs/heads/feature', - push_remove_protected_branch: "570e7b2ab #{Gitlab::Git::BLANK_SHA} "\ - 'refs/heads/feature', - push_tag: '6f6d7e7ed 570e7b2ab refs/tags/v1.0.0', - push_new_tag: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/tags/v7.8.9", - push_all: ['6f6d7e7ed 570e7b2ab refs/heads/master', '6f6d7e7ed 570e7b2ab refs/heads/feature'] - } - end - - def self.permissions_matrix - { - master: { - push_new_branch: true, - push_master: true, - push_protected_branch: true, - push_remove_protected_branch: false, - push_tag: true, - push_new_tag: true, - push_all: true, - }, - - developer: { - push_new_branch: true, - push_master: true, - push_protected_branch: false, - push_remove_protected_branch: false, - push_tag: false, - push_new_tag: true, - push_all: false, - }, - - reporter: { - push_new_branch: false, - push_master: false, - push_protected_branch: false, - push_remove_protected_branch: false, - push_tag: false, - push_new_tag: false, - push_all: false, - }, - - guest: { - push_new_branch: false, - push_master: false, - push_protected_branch: false, - push_remove_protected_branch: false, - push_tag: false, - push_new_tag: false, - push_all: false, - } - } - end - - def self.updated_permissions_matrix - updated_permissions_matrix = permissions_matrix.dup - updated_permissions_matrix[:developer][:push_protected_branch] = true - updated_permissions_matrix[:developer][:push_all] = true - updated_permissions_matrix - end - - permissions_matrix.keys.each do |role| - describe "#{role} access" do - before { protect_feature_branch } - before { project.team << [user, role] } - - permissions_matrix[role].each do |action, allowed| - context action do - subject { access.push_access_check(changes[action]) } - - it { expect(subject.allowed?).to allowed ? be_truthy : be_falsey } - end - end - end - end - - context "with enabled developers push to protected branches " do - updated_permissions_matrix.keys.each do |role| - describe "#{role} access" do - before { create(:protected_branch, name: 'feature', developers_can_push: true, project: project) } - before { project.team << [user, role] } - - updated_permissions_matrix[role].each do |action, allowed| - context action do - subject { access.push_access_check(changes[action]) } - - it { expect(subject.allowed?).to allowed ? be_truthy : be_falsey } - end - end - end - end - end - end -end diff --git a/spec/lib/gitlab/git_access_wiki_spec.rb b/spec/lib/gitlab/git_access_wiki_spec.rb deleted file mode 100644 index 4cb91094cb3bf0bda9ff4352a3a4237e9c90d089..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/git_access_wiki_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GitAccessWiki do - let(:access) { Gitlab::GitAccessWiki.new(user, project) } - let(:project) { create(:project) } - let(:user) { create(:user) } - - describe 'push_allowed?' do - before do - create(:protected_branch, name: 'master', project: project) - project.team << [user, :developer] - end - - subject { access.push_access_check(changes) } - - it { expect(subject.allowed?).to be_truthy } - end - - def changes - ['6f6d7e7ed 570e7b2ab refs/heads/master'] - end -end diff --git a/spec/lib/gitlab/github_import/client_spec.rb b/spec/lib/gitlab/github_import/client_spec.rb deleted file mode 100644 index 26618120316ace4d5aef3ddf6eab3f5b7d546a21..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/github_import/client_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GithubImport::Client do - let(:token) { '123456' } - let(:client) { Gitlab::GithubImport::Client.new(token) } - - before do - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "github") - end - - it 'all OAuth2 client options are symbols' do - client.client.options.keys.each do |key| - expect(key).to be_kind_of(Symbol) - end - end -end diff --git a/spec/lib/gitlab/github_import/project_creator_spec.rb b/spec/lib/gitlab/github_import/project_creator_spec.rb deleted file mode 100644 index 3bf52cb685eae7326329a3dd5b3bd37765827909..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/github_import/project_creator_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GithubImport::ProjectCreator do - let(:user) { create(:user, github_access_token: "asdffg") } - let(:repo) { OpenStruct.new( - login: 'vim', - name: 'vim', - private: true, - full_name: 'asd/vim', - clone_url: "https://gitlab.com/asd/vim.git", - owner: OpenStruct.new(login: "john")) - } - let(:namespace){ create(:group, owner: user) } - - before do - namespace.add_owner(user) - end - - it 'creates project' do - allow_any_instance_of(Project).to receive(:add_import_job) - - project_creator = Gitlab::GithubImport::ProjectCreator.new(repo, namespace, user) - project = project_creator.execute - - expect(project.import_url).to eq("https://asdffg@gitlab.com/asd/vim.git") - expect(project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) - end -end diff --git a/spec/lib/gitlab/gitlab_import/client_spec.rb b/spec/lib/gitlab/gitlab_import/client_spec.rb deleted file mode 100644 index c511c51547409ac98519b97c4b4de59159c4d139..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/gitlab_import/client_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GitlabImport::Client do - let(:token) { '123456' } - let(:client) { Gitlab::GitlabImport::Client.new(token) } - - before do - Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "gitlab") - end - - it 'all OAuth2 client options are symbols' do - client.client.options.keys.each do |key| - expect(key).to be_kind_of(Symbol) - end - end -end diff --git a/spec/lib/gitlab/gitlab_import/project_creator_spec.rb b/spec/lib/gitlab/gitlab_import/project_creator_spec.rb deleted file mode 100644 index 3cefe4ea8e2058d29df8014139b9d04ebdbecc44..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/gitlab_import/project_creator_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GitlabImport::ProjectCreator do - let(:user) { create(:user, gitlab_access_token: "asdffg") } - let(:repo) { { - name: 'vim', - path: 'vim', - visibility_level: Gitlab::VisibilityLevel::PRIVATE, - path_with_namespace: 'asd/vim', - http_url_to_repo: "https://gitlab.com/asd/vim.git", - owner: {name: "john"}}.with_indifferent_access - } - let(:namespace){ create(:group, owner: user) } - - before do - namespace.add_owner(user) - end - - it 'creates project' do - allow_any_instance_of(Project).to receive(:add_import_job) - - project_creator = Gitlab::GitlabImport::ProjectCreator.new(repo, namespace, user) - project = project_creator.execute - - expect(project.import_url).to eq("https://oauth2:asdffg@gitlab.com/asd/vim.git") - expect(project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) - end -end diff --git a/spec/lib/gitlab/gitlab_markdown_helper_spec.rb b/spec/lib/gitlab/gitlab_markdown_helper_spec.rb deleted file mode 100644 index ab613193f41de7f355312961204c7aafc1d8074f..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/gitlab_markdown_helper_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe Gitlab::MarkdownHelper do - describe '#markup?' do - %w(textile rdoc org creole wiki - mediawiki rst adoc asciidoc asc).each do |type| - it "returns true for #{type} files" do - expect(Gitlab::MarkdownHelper.markup?("README.#{type}")).to be_truthy - end - end - - it 'returns false when given a non-markup filename' do - expect(Gitlab::MarkdownHelper.markup?('README.rb')).not_to be_truthy - end - end - - describe '#gitlab_markdown?' do - %w(mdown md markdown).each do |type| - it "returns true for #{type} files" do - expect(Gitlab::MarkdownHelper.gitlab_markdown?("README.#{type}")).to be_truthy - end - end - - it 'returns false when given a non-markdown filename' do - expect(Gitlab::MarkdownHelper.gitlab_markdown?('README.rb')).not_to be_truthy - end - end -end diff --git a/spec/lib/gitlab/gitorious_import/project_creator_spec.rb b/spec/lib/gitlab/gitorious_import/project_creator_spec.rb deleted file mode 100644 index c1125ca63574849b61f7112480ab9e45cd731a52..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/gitorious_import/project_creator_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GitoriousImport::ProjectCreator do - let(:user) { create(:user) } - let(:repo) { Gitlab::GitoriousImport::Repository.new('foo/bar-baz-qux') } - let(:namespace){ create(:group, owner: user) } - - before do - namespace.add_owner(user) - end - - it 'creates project' do - allow_any_instance_of(Project).to receive(:add_import_job) - - project_creator = Gitlab::GitoriousImport::ProjectCreator.new(repo, namespace, user) - project = project_creator.execute - - expect(project.name).to eq("Bar Baz Qux") - expect(project.path).to eq("bar-baz-qux") - expect(project.namespace).to eq(namespace) - expect(project.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC) - expect(project.import_type).to eq("gitorious") - expect(project.import_source).to eq("foo/bar-baz-qux") - expect(project.import_url).to eq("https://gitorious.org/foo/bar-baz-qux.git") - end -end diff --git a/spec/lib/gitlab/google_code_import/client_spec.rb b/spec/lib/gitlab/google_code_import/client_spec.rb deleted file mode 100644 index d2bf871daa8bd1133375669d7a6e53c61258490d..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/google_code_import/client_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require "spec_helper" - -describe Gitlab::GoogleCodeImport::Client do - let(:raw_data) { JSON.parse(File.read(Rails.root.join("spec/fixtures/GoogleCodeProjectHosting.json"))) } - subject { described_class.new(raw_data) } - - describe "#valid?" do - context "when the data is valid" do - it "returns true" do - expect(subject).to be_valid - end - end - - context "when the data is invalid" do - let(:raw_data) { "No clue" } - - it "returns true" do - expect(subject).to_not be_valid - end - end - end - - describe "#repos" do - it "returns only Git repositories" do - expect(subject.repos.length).to eq(1) - end - end - - describe "#repo" do - it "returns the referenced repository" do - expect(subject.repo("tint2").name).to eq("tint2") - end - end -end diff --git a/spec/lib/gitlab/google_code_import/project_creator_spec.rb b/spec/lib/gitlab/google_code_import/project_creator_spec.rb deleted file mode 100644 index 7a224538b8be40c732f4f258a09a4318bc72c305..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/google_code_import/project_creator_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' - -describe Gitlab::GoogleCodeImport::ProjectCreator do - let(:user) { create(:user) } - let(:repo) { - Gitlab::GoogleCodeImport::Repository.new( - "name" => 'vim', - "summary" => 'VI Improved', - "repositoryUrls" => [ "https://vim.googlecode.com/git/" ] - ) - } - let(:namespace){ create(:group, owner: user) } - - before do - namespace.add_owner(user) - end - - it 'creates project' do - allow_any_instance_of(Project).to receive(:add_import_job) - - project_creator = Gitlab::GoogleCodeImport::ProjectCreator.new(repo, namespace, user) - project = project_creator.execute - - expect(project.import_url).to eq("https://vim.googlecode.com/git/") - expect(project.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC) - end -end diff --git a/spec/lib/gitlab/key_fingerprint_spec.rb b/spec/lib/gitlab/key_fingerprint_spec.rb deleted file mode 100644 index 266eab6e7932351a7372795cb29fdcc24f4eeefe..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/key_fingerprint_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -require "spec_helper" - -describe Gitlab::KeyFingerprint do - let(:key) { "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" } - let(:fingerprint) { "3f:a2:ee:de:b5:de:53:c3:aa:2f:9c:45:24:4c:47:7b" } - - describe "#fingerprint" do - it "generates the key's fingerprint" do - expect(Gitlab::KeyFingerprint.new(key).fingerprint).to eq(fingerprint) - end - end -end diff --git a/spec/lib/gitlab/ldap/access_spec.rb b/spec/lib/gitlab/ldap/access_spec.rb deleted file mode 100644 index 707a0521ab3a0a670c0ba5156ca7ad1d2f4b5aab..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/ldap/access_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -require 'spec_helper' - -describe Gitlab::LDAP::Access do - let(:access) { Gitlab::LDAP::Access.new user } - let(:user) { create(:omniauth_user) } - - describe :allowed? do - subject { access.allowed? } - - context 'when the user cannot be found' do - before { Gitlab::LDAP::Person.stub(find_by_dn: nil) } - - it { is_expected.to be_falsey } - end - - context 'when the user is found' do - before { Gitlab::LDAP::Person.stub(find_by_dn: :ldap_user) } - - context 'and the user is diabled via active directory' do - before { Gitlab::LDAP::Person.stub(disabled_via_active_directory?: true) } - - it { is_expected.to be_falsey } - - it "should block user in GitLab" do - access.allowed? - user.should be_blocked - end - end - - context 'and has no disabled flag in active diretory' do - before do - user.block - - Gitlab::LDAP::Person.stub(disabled_via_active_directory?: false) - end - - it { is_expected.to be_truthy } - - it "should unblock user in GitLab" do - access.allowed? - user.should_not be_blocked - end - end - - context 'without ActiveDirectory enabled' do - before do - Gitlab::LDAP::Config.stub(enabled?: true) - Gitlab::LDAP::Config.any_instance.stub(active_directory: false) - end - - it { is_expected.to be_truthy } - end - end - end -end diff --git a/spec/lib/gitlab/ldap/adapter_spec.rb b/spec/lib/gitlab/ldap/adapter_spec.rb deleted file mode 100644 index b609e4b38f21c28c21445bded0723288922e1906..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/ldap/adapter_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'spec_helper' - -describe Gitlab::LDAP::Adapter do - let(:adapter) { Gitlab::LDAP::Adapter.new 'ldapmain' } - - describe :dn_matches_filter? do - let(:ldap) { double(:ldap) } - subject { adapter.dn_matches_filter?(:dn, :filter) } - before { adapter.stub(ldap: ldap) } - - context "when the search is successful" do - context "and the result is non-empty" do - before { ldap.stub(search: [:foo]) } - - it { is_expected.to be_truthy } - end - - context "and the result is empty" do - before { ldap.stub(search: []) } - - it { is_expected.to be_falsey } - end - end - - context "when the search encounters an error" do - before { ldap.stub(search: nil, get_operation_result: double(code: 1, message: 'some error')) } - - it { is_expected.to be_falsey } - end - end -end diff --git a/spec/lib/gitlab/ldap/authentication_spec.rb b/spec/lib/gitlab/ldap/authentication_spec.rb deleted file mode 100644 index 8afc2b21f467ac848fadfea567ff32f3a2f27c39..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/ldap/authentication_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'spec_helper' - -describe Gitlab::LDAP::Authentication do - let(:klass) { Gitlab::LDAP::Authentication } - let(:user) { create(:omniauth_user, extern_uid: dn) } - let(:dn) { 'uid=john,ou=people,dc=example,dc=com' } - let(:login) { 'john' } - let(:password) { 'password' } - - describe :login do - let(:adapter) { double :adapter } - before do - Gitlab::LDAP::Config.stub(enabled?: true) - end - - it "finds the user if authentication is successful" do - user - # try only to fake the LDAP call - klass.any_instance.stub(adapter: double(:adapter, - bind_as: double(:ldap_user, dn: dn) - )) - expect(klass.login(login, password)).to be_truthy - end - - it "is false if the user does not exist" do - # try only to fake the LDAP call - klass.any_instance.stub(adapter: double(:adapter, - bind_as: double(:ldap_user, dn: dn) - )) - expect(klass.login(login, password)).to be_falsey - end - - it "is false if authentication fails" do - user - # try only to fake the LDAP call - klass.any_instance.stub(adapter: double(:adapter, bind_as: nil)) - expect(klass.login(login, password)).to be_falsey - end - - it "fails if ldap is disabled" do - Gitlab::LDAP::Config.stub(enabled?: false) - expect(klass.login(login, password)).to be_falsey - end - - it "fails if no login is supplied" do - expect(klass.login('', password)).to be_falsey - end - - it "fails if no password is supplied" do - expect(klass.login(login, '')).to be_falsey - end - end -end \ No newline at end of file diff --git a/spec/lib/gitlab/ldap/config_spec.rb b/spec/lib/gitlab/ldap/config_spec.rb deleted file mode 100644 index 00e9076c787b18e64a9b3f39a6e685ca5f4786f8..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/ldap/config_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'spec_helper' - -describe Gitlab::LDAP::Config do - let(:config) { Gitlab::LDAP::Config.new provider } - let(:provider) { 'ldapmain' } - - describe '#initalize' do - it 'requires a provider' do - expect{ Gitlab::LDAP::Config.new }.to raise_error ArgumentError - end - - it "works" do - expect(config).to be_a described_class - end - - it "raises an error if a unknow provider is used" do - expect{ Gitlab::LDAP::Config.new 'unknown' }.to raise_error - end - end -end diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb deleted file mode 100644 index 42015c28c81ab6cb64695624c790a6522559d94e..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/ldap/user_spec.rb +++ /dev/null @@ -1,106 +0,0 @@ -require 'spec_helper' - -describe Gitlab::LDAP::User do - let(:ldap_user) { Gitlab::LDAP::User.new(auth_hash) } - let(:gl_user) { ldap_user.gl_user } - let(:info) do - { - name: 'John', - email: 'john@example.com', - nickname: 'john' - } - end - let(:auth_hash) do - double(uid: 'my-uid', provider: 'ldapmain', info: double(info)) - end - - describe :changed? do - it "marks existing ldap user as changed" do - existing_user = create(:omniauth_user, extern_uid: 'my-uid', provider: 'ldapmain') - expect(ldap_user.changed?).to be_truthy - end - - it "marks existing non-ldap user if the email matches as changed" do - existing_user = create(:user, email: 'john@example.com') - expect(ldap_user.changed?).to be_truthy - end - - it "dont marks existing ldap user as changed" do - existing_user = create(:omniauth_user, email: 'john@example.com', extern_uid: 'my-uid', provider: 'ldapmain') - expect(ldap_user.changed?).to be_falsey - end - end - - describe :find_or_create do - it "finds the user if already existing" do - existing_user = create(:omniauth_user, extern_uid: 'my-uid', provider: 'ldapmain') - - expect{ ldap_user.save }.to_not change{ User.count } - end - - it "connects to existing non-ldap user if the email matches" do - existing_user = create(:omniauth_user, email: 'john@example.com', provider: "twitter") - expect{ ldap_user.save }.to_not change{ User.count } - - existing_user.reload - expect(existing_user.ldap_identity.extern_uid).to eql 'my-uid' - expect(existing_user.ldap_identity.provider).to eql 'ldapmain' - end - - it "creates a new user if not found" do - expect{ ldap_user.save }.to change{ User.count }.by(1) - end - end - - - describe 'blocking' do - context 'signup' do - context 'dont block on create' do - before { Gitlab::LDAP::Config.any_instance.stub block_auto_created_users: false } - - it do - ldap_user.save - expect(gl_user).to be_valid - expect(gl_user).not_to be_blocked - end - end - - context 'block on create' do - before { Gitlab::LDAP::Config.any_instance.stub block_auto_created_users: true } - - it do - ldap_user.save - expect(gl_user).to be_valid - expect(gl_user).to be_blocked - end - end - end - - context 'sign-in' do - before do - ldap_user.save - ldap_user.gl_user.activate - end - - context 'dont block on create' do - before { Gitlab::LDAP::Config.any_instance.stub block_auto_created_users: false } - - it do - ldap_user.save - expect(gl_user).to be_valid - expect(gl_user).not_to be_blocked - end - end - - context 'block on create' do - before { Gitlab::LDAP::Config.any_instance.stub block_auto_created_users: true } - - it do - ldap_user.save - expect(gl_user).to be_valid - expect(gl_user).not_to be_blocked - end - end - end - end -end diff --git a/spec/lib/gitlab/note_data_builder_spec.rb b/spec/lib/gitlab/note_data_builder_spec.rb deleted file mode 100644 index 448cd0c6880dcd58c23174cc62de6deec7453c2a..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/note_data_builder_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'spec_helper' - -describe 'Gitlab::NoteDataBuilder' do - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:data) { Gitlab::NoteDataBuilder.build(note, user) } - let(:note_url) { Gitlab::UrlBuilder.new(:note).build(note.id) } - let(:fixed_time) { Time.at(1425600000) } # Avoid time precision errors - - before(:each) do - expect(data).to have_key(:object_attributes) - expect(data[:object_attributes]).to have_key(:url) - expect(data[:object_attributes][:url]).to eq(note_url) - expect(data[:object_kind]).to eq('note') - expect(data[:user]).to eq(user.hook_attrs) - end - - describe 'When asking for a note on commit' do - let(:note) { create(:note_on_commit) } - - it 'returns the note and commit-specific data' do - expect(data).to have_key(:commit) - end - end - - describe 'When asking for a note on commit diff' do - let(:note) { create(:note_on_commit_diff) } - - it 'returns the note and commit-specific data' do - expect(data).to have_key(:commit) - end - end - - describe 'When asking for a note on issue' do - let(:issue) { create(:issue, created_at: fixed_time, updated_at: fixed_time) } - let(:note) { create(:note_on_issue, noteable_id: issue.id) } - - it 'returns the note and issue-specific data' do - expect(data).to have_key(:issue) - expect(data[:issue]).to eq(issue.hook_attrs) - end - end - - describe 'When asking for a note on merge request' do - let(:merge_request) { create(:merge_request, created_at: fixed_time, updated_at: fixed_time) } - let(:note) { create(:note_on_merge_request, noteable_id: merge_request.id) } - - it 'returns the note and merge request data' do - expect(data).to have_key(:merge_request) - expect(data[:merge_request]).to eq(merge_request.hook_attrs) - end - end - - describe 'When asking for a note on merge request diff' do - let(:merge_request) { create(:merge_request, created_at: fixed_time, updated_at: fixed_time) } - let(:note) { create(:note_on_merge_request_diff, noteable_id: merge_request.id) } - - it 'returns the note and merge request diff data' do - expect(data).to have_key(:merge_request) - expect(data[:merge_request]).to eq(merge_request.hook_attrs) - end - end - - describe 'When asking for a note on project snippet' do - let!(:snippet) { create(:project_snippet, created_at: fixed_time, updated_at: fixed_time) } - let!(:note) { create(:note_on_project_snippet, noteable_id: snippet.id) } - - it 'returns the note and project snippet data' do - expect(data).to have_key(:snippet) - expect(data[:snippet]).to eq(snippet.hook_attrs) - end - end -end diff --git a/spec/lib/gitlab/o_auth/auth_hash_spec.rb b/spec/lib/gitlab/o_auth/auth_hash_spec.rb deleted file mode 100644 index 5eb77b492b2c1c0357da42f3c353d80a62aa3e6b..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/o_auth/auth_hash_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -require 'spec_helper' - -describe Gitlab::OAuth::AuthHash do - let(:auth_hash) do - Gitlab::OAuth::AuthHash.new(double({ - provider: 'twitter', - uid: uid, - info: double(info_hash) - })) - end - let(:uid) { 'my-uid' } - let(:email) { 'my-email@example.com' } - let(:nickname) { 'my-nickname' } - let(:info_hash) { - { - email: email, - nickname: nickname, - name: 'John', - first_name: "John", - last_name: "Who" - } - } - - context "defaults" do - it { expect(auth_hash.provider).to eql 'twitter' } - it { expect(auth_hash.uid).to eql uid } - it { expect(auth_hash.email).to eql email } - it { expect(auth_hash.username).to eql nickname } - it { expect(auth_hash.name).to eql "John" } - it { expect(auth_hash.password).to_not be_empty } - end - - context "email not provided" do - before { info_hash.delete(:email) } - it "generates a temp email" do - expect( auth_hash.email).to start_with('temp-email-for-oauth') - end - end - - context "username not provided" do - before { info_hash.delete(:nickname) } - - it "takes the first part of the email as username" do - expect( auth_hash.username ).to eql "my-email" - end - end - - context "name not provided" do - before { info_hash.delete(:name) } - - it "concats first and lastname as the name" do - expect( auth_hash.name ).to eql "John Who" - end - end -end \ No newline at end of file diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb deleted file mode 100644 index 44cdd1e4fab191ee3d8f90166c3e6274b5131e9d..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ /dev/null @@ -1,109 +0,0 @@ -require 'spec_helper' - -describe Gitlab::OAuth::User do - let(:oauth_user) { Gitlab::OAuth::User.new(auth_hash) } - let(:gl_user) { oauth_user.gl_user } - let(:uid) { 'my-uid' } - let(:provider) { 'my-provider' } - let(:auth_hash) { double(uid: uid, provider: provider, info: double(info_hash)) } - let(:info_hash) do - { - nickname: '-john+gitlab-ETC%.git@gmail.com', - name: 'John', - email: 'john@mail.com' - } - end - - describe :persisted? do - let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') } - - it "finds an existing user based on uid and provider (facebook)" do - auth = double(info: double(name: 'John'), uid: 'my-uid', provider: 'my-provider') - expect( oauth_user.persisted? ).to be_truthy - end - - it "returns false if use is not found in database" do - auth_hash.stub(uid: 'non-existing') - expect( oauth_user.persisted? ).to be_falsey - end - end - - describe :save do - let(:provider) { 'twitter' } - - describe 'signup' do - context "with allow_single_sign_on enabled" do - before { Gitlab.config.omniauth.stub allow_single_sign_on: true } - - it "creates a user from Omniauth" do - oauth_user.save - - expect(gl_user).to be_valid - identity = gl_user.identities.first - expect(identity.extern_uid).to eql uid - expect(identity.provider).to eql 'twitter' - end - end - - context "with allow_single_sign_on disabled (Default)" do - it "throws an error" do - expect{ oauth_user.save }.to raise_error StandardError - end - end - end - - describe 'blocking' do - let(:provider) { 'twitter' } - before { Gitlab.config.omniauth.stub allow_single_sign_on: true } - - context 'signup' do - context 'dont block on create' do - before { Gitlab.config.omniauth.stub block_auto_created_users: false } - - it do - oauth_user.save - expect(gl_user).to be_valid - expect(gl_user).not_to be_blocked - end - end - - context 'block on create' do - before { Gitlab.config.omniauth.stub block_auto_created_users: true } - - it do - oauth_user.save - expect(gl_user).to be_valid - expect(gl_user).to be_blocked - end - end - end - - context 'sign-in' do - before do - oauth_user.save - oauth_user.gl_user.activate - end - - context 'dont block on create' do - before { Gitlab.config.omniauth.stub block_auto_created_users: false } - - it do - oauth_user.save - expect(gl_user).to be_valid - expect(gl_user).not_to be_blocked - end - end - - context 'block on create' do - before { Gitlab.config.omniauth.stub block_auto_created_users: true } - - it do - oauth_user.save - expect(gl_user).to be_valid - expect(gl_user).not_to be_blocked - end - end - end - end - end -end diff --git a/spec/lib/gitlab/popen_spec.rb b/spec/lib/gitlab/popen_spec.rb deleted file mode 100644 index cd9d0456b25c29b51ad8ceceed11dc67d00af87c..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/popen_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -require 'spec_helper' - -describe 'Gitlab::Popen', no_db: true do - let (:path) { Rails.root.join('tmp').to_s } - - before do - @klass = Class.new(Object) - @klass.send(:include, Gitlab::Popen) - end - - context 'zero status' do - before do - @output, @status = @klass.new.popen(%W(ls), path) - end - - it { expect(@status).to be_zero } - it { expect(@output).to include('cache') } - end - - context 'non-zero status' do - before do - @output, @status = @klass.new.popen(%W(cat NOTHING), path) - end - - it { expect(@status).to eq(1) } - it { expect(@output).to include('No such file or directory') } - end - - context 'unsafe string command' do - it 'raises an error when it gets called with a string argument' do - expect { @klass.new.popen('ls', path) }.to raise_error - end - end - - context 'without a directory argument' do - before do - @output, @status = @klass.new.popen(%W(ls)) - end - - it { expect(@status).to be_zero } - it { expect(@output).to include('spec') } - end - -end - diff --git a/spec/lib/gitlab/push_data_builder_spec.rb b/spec/lib/gitlab/push_data_builder_spec.rb deleted file mode 100644 index 1b8ba7b4d4333d300f62845d8bfccaf1060ced1a..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/push_data_builder_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'spec_helper' - -describe 'Gitlab::PushDataBuilder' do - let(:project) { create(:project) } - let(:user) { create(:user) } - - - describe :build_sample do - let(:data) { Gitlab::PushDataBuilder.build_sample(project, user) } - - it { expect(data).to be_a(Hash) } - it { expect(data[:before]).to eq('6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') } - it { expect(data[:after]).to eq('5937ac0a7beb003549fc5fd26fc247adbce4a52e') } - it { expect(data[:ref]).to eq('refs/heads/master') } - it { expect(data[:commits].size).to eq(3) } - it { expect(data[:repository][:git_http_url]).to eq(project.http_url_to_repo) } - it { expect(data[:repository][:git_ssh_url]).to eq(project.ssh_url_to_repo) } - it { expect(data[:repository][:visibility_level]).to eq(project.visibility_level) } - it { expect(data[:total_commits_count]).to eq(3) } - end - - describe :build do - let(:data) do - Gitlab::PushDataBuilder.build(project, - user, - Gitlab::Git::BLANK_SHA, - '8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b', - 'refs/tags/v1.1.0') - end - - it { expect(data).to be_a(Hash) } - it { expect(data[:before]).to eq(Gitlab::Git::BLANK_SHA) } - it { expect(data[:checkout_sha]).to eq('5937ac0a7beb003549fc5fd26fc247adbce4a52e') } - it { expect(data[:after]).to eq('8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b') } - it { expect(data[:ref]).to eq('refs/tags/v1.1.0') } - it { expect(data[:commits]).to be_empty } - it { expect(data[:total_commits_count]).to be_zero } - end -end diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb deleted file mode 100644 index c9fb62b61ae7a8218efc464484e362baf4685e60..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ /dev/null @@ -1,156 +0,0 @@ -require 'spec_helper' - -describe Gitlab::ReferenceExtractor do - let(:project) { create(:project) } - subject { Gitlab::ReferenceExtractor.new(project, project.creator) } - - it 'extracts username references' do - subject.analyze('this contains a @user reference') - expect(subject.references[:user]).to eq([[project, 'user']]) - end - - it 'extracts issue references' do - subject.analyze('this one talks about issue #1234') - expect(subject.references[:issue]).to eq([[project, '1234']]) - end - - it 'extracts JIRA issue references' do - subject.analyze('this one talks about issue JIRA-1234') - expect(subject.references[:issue]).to eq([[project, 'JIRA-1234']]) - end - - it 'extracts merge request references' do - subject.analyze("and here's !43, a merge request") - expect(subject.references[:merge_request]).to eq([[project, '43']]) - end - - it 'extracts snippet ids' do - subject.analyze('snippets like $12 get extracted as well') - expect(subject.references[:snippet]).to eq([[project, '12']]) - end - - it 'extracts commit shas' do - subject.analyze('commit shas 98cf0ae3 are pulled out as Strings') - expect(subject.references[:commit]).to eq([[project, '98cf0ae3']]) - end - - it 'extracts commit ranges' do - subject.analyze('here you go, a commit range: 98cf0ae3...98cf0ae4') - expect(subject.references[:commit_range]).to eq([[project, '98cf0ae3...98cf0ae4']]) - end - - it 'extracts multiple references and preserves their order' do - subject.analyze('@me and @you both care about this') - expect(subject.references[:user]).to eq([ - [project, 'me'], - [project, 'you'] - ]) - end - - it 'leaves the original note unmodified' do - text = 'issue #123 is just the worst, @user' - subject.analyze(text) - expect(text).to eq('issue #123 is just the worst, @user') - end - - it 'extracts no references for
    ..
    blocks' do - subject.analyze("
    def puts '#1 issue'\nend\n
    ```") - expect(subject.issues).to be_blank - end - - it 'extracts no references for .. blocks' do - subject.analyze("def puts '!1 request'\nend\n```") - expect(subject.merge_requests).to be_blank - end - - it 'extracts no references for code blocks with language' do - subject.analyze("this code:\n```ruby\ndef puts '#1 issue'\nend\n```") - expect(subject.issues).to be_blank - end - - it 'extracts issue references for invalid code blocks' do - subject.analyze('test: ```this one talks about issue #1234```') - expect(subject.references[:issue]).to eq([[project, '1234']]) - end - - it 'handles all possible kinds of references' do - accessors = Gitlab::Markdown::TYPES.map { |t| "#{t}s".to_sym } - expect(subject).to respond_to(*accessors) - end - - it 'accesses valid user objects' do - @u_foo = create(:user, username: 'foo') - @u_bar = create(:user, username: 'bar') - @u_offteam = create(:user, username: 'offteam') - - project.team << [@u_foo, :reporter] - project.team << [@u_bar, :guest] - - subject.analyze('@foo, @baduser, @bar, and @offteam') - expect(subject.users).to eq([@u_foo, @u_bar, @u_offteam]) - end - - it 'accesses valid issue objects' do - @i0 = create(:issue, project: project) - @i1 = create(:issue, project: project) - - subject.analyze("##{@i0.iid}, ##{@i1.iid}, and #999.") - expect(subject.issues).to eq([@i0, @i1]) - end - - it 'accesses valid merge requests' do - @m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'aaa') - @m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'bbb') - - subject.analyze("!999, !#{@m1.iid}, and !#{@m0.iid}.") - expect(subject.merge_requests).to eq([@m1, @m0]) - end - - it 'accesses valid snippets' do - @s0 = create(:project_snippet, project: project) - @s1 = create(:project_snippet, project: project) - @s2 = create(:project_snippet) - - subject.analyze("$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}") - expect(subject.snippets).to eq([@s0, @s1]) - end - - it 'accesses valid commits' do - commit = project.repository.commit('master') - - subject.analyze("this references commits #{commit.sha[0..6]} and 012345") - extracted = subject.commits - expect(extracted.size).to eq(1) - expect(extracted[0].sha).to eq(commit.sha) - expect(extracted[0].message).to eq(commit.message) - end - - it 'accesses valid commit ranges' do - commit = project.repository.commit('master') - earlier_commit = project.repository.commit('master~2') - - subject.analyze("this references commits #{earlier_commit.sha[0..6]}...#{commit.sha[0..6]}") - extracted = subject.commit_ranges - expect(extracted.size).to eq(1) - expect(extracted[0][0].sha).to eq(earlier_commit.sha) - expect(extracted[0][0].message).to eq(earlier_commit.message) - expect(extracted[0][1].sha).to eq(commit.sha) - expect(extracted[0][1].message).to eq(commit.message) - end - - context 'with a project with an underscore' do - let(:other_project) { create(:project, path: 'test_project') } - let(:issue) { create(:issue, project: other_project) } - - before do - other_project.team << [project.creator, :developer] - end - - it 'handles project issue references' do - subject.analyze("this refers issue #{other_project.path_with_namespace}##{issue.iid}") - extracted = subject.issues - expect(extracted.size).to eq(1) - expect(extracted).to eq([issue]) - end - end -end diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb deleted file mode 100644 index 727884c41c5565dc215e322b147fe6cc38932cb5..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/regex_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Regex do - describe 'project path regex' do - it { expect('gitlab-ce').to match(Gitlab::Regex.project_path_regex) } - it { expect('gitlab_git').to match(Gitlab::Regex.project_path_regex) } - it { expect('_underscore.js').to match(Gitlab::Regex.project_path_regex) } - it { expect('100px.com').to match(Gitlab::Regex.project_path_regex) } - it { expect('?gitlab').not_to match(Gitlab::Regex.project_path_regex) } - it { expect('git lab').not_to match(Gitlab::Regex.project_path_regex) } - it { expect('gitlab.git').not_to match(Gitlab::Regex.project_path_regex) } - end - - describe 'project name regex' do - it { expect('gitlab-ce').to match(Gitlab::Regex.project_name_regex) } - it { expect('GitLab CE').to match(Gitlab::Regex.project_name_regex) } - it { expect('100 lines').to match(Gitlab::Regex.project_name_regex) } - it { expect('gitlab.git').to match(Gitlab::Regex.project_name_regex) } - it { expect('?gitlab').not_to match(Gitlab::Regex.project_name_regex) } - end -end diff --git a/spec/lib/gitlab/satellite/action_spec.rb b/spec/lib/gitlab/satellite/action_spec.rb deleted file mode 100644 index 28e3d64ee2be0528484216f6dac785cd74de7339..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/satellite/action_spec.rb +++ /dev/null @@ -1,118 +0,0 @@ -require 'spec_helper' - -describe 'Gitlab::Satellite::Action' do - let(:project) { create(:project) } - let(:user) { create(:user) } - - describe '#prepare_satellite!' do - it 'should be able to fetch timeout from conf' do - expect(Gitlab::Satellite::Action::DEFAULT_OPTIONS[:git_timeout]).to eq(30.seconds) - end - - it 'create a repository with a parking branch and one remote: origin' do - repo = project.satellite.repo - - #now lets dirty it up - - starting_remote_count = repo.git.list_remotes.size - expect(starting_remote_count).to be >= 1 - #kind of hookey way to add a second remote - origin_uri = repo.git.remote({v: true}).split(" ")[1] - begin - repo.git.remote({raise: true}, 'add', 'another-remote', origin_uri) - repo.git.branch({raise: true}, 'a-new-branch') - - expect(repo.heads.size).to be > (starting_remote_count) - expect(repo.git.remote().split(" ").size).to be > (starting_remote_count) - rescue - end - - repo.git.config({}, "user.name", "#{user.name} -- foo") - repo.git.config({}, "user.email", "#{user.email} -- foo") - expect(repo.config['user.name']).to eq("#{user.name} -- foo") - expect(repo.config['user.email']).to eq("#{user.email} -- foo") - - - #These must happen in the context of the satellite directory... - satellite_action = Gitlab::Satellite::Action.new(user, project) - project.satellite.lock { - #Now clean it up, use send to get around prepare_satellite! being protected - satellite_action.send(:prepare_satellite!, repo) - } - - #verify it's clean - heads = repo.heads.map(&:name) - expect(heads.size).to eq(1) - expect(heads.include?(Gitlab::Satellite::Satellite::PARKING_BRANCH)).to eq(true) - remotes = repo.git.remote().split(' ') - expect(remotes.size).to eq(1) - expect(remotes.include?('origin')).to eq(true) - expect(repo.config['user.name']).to eq(user.name) - expect(repo.config['user.email']).to eq(user.email) - end - end - - describe '#in_locked_and_timed_satellite' do - - it 'should make use of a lockfile' do - repo = project.satellite.repo - called = false - - #set assumptions - FileUtils.rm_f(project.satellite.lock_file) - - expect(File.exists?(project.satellite.lock_file)).to be_falsey - - satellite_action = Gitlab::Satellite::Action.new(user, project) - satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo| - expect(repo).to eq(sat_repo) - expect(File.exists? project.satellite.lock_file).to be_truthy - called = true - end - - expect(called).to be_truthy - - end - - it 'should be able to use the satellite after locking' do - repo = project.satellite.repo - called = false - - # Set base assumptions - if File.exists? project.satellite.lock_file - expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_falsey - end - - satellite_action = Gitlab::Satellite::Action.new(user, project) - satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo| - called = true - expect(repo).to eq(sat_repo) - expect(File.exists? project.satellite.lock_file).to be_truthy - expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_truthy - end - - expect(called).to be_truthy - expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_falsey - - end - - class FileLockStatusChecker < File - def flocked?(&block) - status = flock LOCK_EX|LOCK_NB - case status - when false - return true - when 0 - begin - block ? block.call : false - ensure - flock LOCK_UN - end - else - raise SystemCallError, status - end - end - end - - end -end diff --git a/spec/lib/gitlab/satellite/merge_action_spec.rb b/spec/lib/gitlab/satellite/merge_action_spec.rb deleted file mode 100644 index 915e3ff0e5167219787780ca4b7f994fb1e2cb59..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/satellite/merge_action_spec.rb +++ /dev/null @@ -1,104 +0,0 @@ -require 'spec_helper' - -describe 'Gitlab::Satellite::MergeAction' do - include RepoHelpers - - let(:project) { create(:project, namespace: create(:group)) } - let(:fork_project) { create(:project, namespace: create(:group), forked_from_project: project) } - let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let(:merge_request_fork) { create(:merge_request, source_project: fork_project, target_project: project) } - - let(:merge_request_with_conflict) { create(:merge_request, :conflict, source_project: project, target_project: project) } - let(:merge_request_fork_with_conflict) { create(:merge_request, :conflict, source_project: project, target_project: project) } - - describe '#commits_between' do - def verify_commits(commits, first_commit_sha, last_commit_sha) - commits.each { |commit| expect(commit.class).to eq(Gitlab::Git::Commit) } - expect(commits.first.id).to eq(first_commit_sha) - expect(commits.last.id).to eq(last_commit_sha) - end - - context 'on fork' do - it 'should get proper commits between' do - commits = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).commits_between - verify_commits(commits, sample_compare.commits.first, sample_compare.commits.last) - end - end - - context 'between branches' do - it 'should raise exception -- not expected to be used by non forks' do - expect { Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between }.to raise_error - end - end - end - - describe '#format_patch' do - def verify_content(patch) - sample_compare.commits.each do |commit| - expect(patch.include?(commit)).to be_truthy - end - end - - context 'on fork' do - it 'should build a format patch' do - patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).format_patch - verify_content(patch) - end - end - - context 'between branches' do - it 'should build a format patch' do - patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request).format_patch - verify_content(patch) - end - end - end - - describe '#diffs_between_satellite tested against diff_in_satellite' do - def is_a_matching_diff(diff, diffs) - diff_count = diff.scan('diff --git').size - expect(diff_count).to be >= 1 - expect(diffs.size).to eq(diff_count) - diffs.each do |a_diff| - expect(a_diff.class).to eq(Gitlab::Git::Diff) - expect(diff.include? a_diff.diff).to be_truthy - end - end - - context 'on fork' do - it 'should get proper diffs' do - diffs = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).diffs_between_satellite - diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request_fork).diff_in_satellite - is_a_matching_diff(diff, diffs) - end - end - - context 'between branches' do - it 'should get proper diffs' do - expect{ Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite }.to raise_error - end - end - end - - describe '#can_be_merged?' do - context 'on fork' do - it { expect(Gitlab::Satellite::MergeAction.new( - merge_request_fork.author, - merge_request_fork).can_be_merged?).to be_truthy } - - it { expect(Gitlab::Satellite::MergeAction.new( - merge_request_fork_with_conflict.author, - merge_request_fork_with_conflict).can_be_merged?).to be_falsey } - end - - context 'between branches' do - it { expect(Gitlab::Satellite::MergeAction.new( - merge_request.author, - merge_request).can_be_merged?).to be_truthy } - - it { expect(Gitlab::Satellite::MergeAction.new( - merge_request_with_conflict.author, - merge_request_with_conflict).can_be_merged?).to be_falsey } - end - end -end diff --git a/spec/lib/gitlab/upgrader_spec.rb b/spec/lib/gitlab/upgrader_spec.rb deleted file mode 100644 index ce3ea6c260aa66659caa758c328cb00f8a3a9fcf..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/upgrader_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'spec_helper' - -describe Gitlab::Upgrader do - let(:upgrader) { Gitlab::Upgrader.new } - let(:current_version) { Gitlab::VERSION } - - describe 'current_version_raw' do - it { expect(upgrader.current_version_raw).to eq(current_version) } - end - - describe 'latest_version?' do - it 'should be true if newest version' do - upgrader.stub(latest_version_raw: current_version) - expect(upgrader.latest_version?).to be_truthy - end - end - - describe 'latest_version_raw' do - it 'should be latest version for GitLab 5' do - upgrader.stub(current_version_raw: "5.3.0") - expect(upgrader.latest_version_raw).to eq("v5.4.2") - end - end -end diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb deleted file mode 100644 index 5153ed15af3f865fed83d30545d9d99a82685639..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/url_builder_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'spec_helper' - -describe Gitlab::UrlBuilder do - describe 'When asking for an issue' do - it 'returns the issue url' do - issue = create(:issue) - url = Gitlab::UrlBuilder.new(:issue).build(issue.id) - expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.path_with_namespace}/issues/#{issue.iid}" - end - end - - describe 'When asking for an merge request' do - it 'returns the merge request url' do - merge_request = create(:merge_request) - url = Gitlab::UrlBuilder.new(:merge_request).build(merge_request.id) - expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}" - end - end - - describe 'When asking for a note on commit' do - let(:note) { create(:note_on_commit) } - let(:url) { Gitlab::UrlBuilder.new(:note).build(note.id) } - - it 'returns the note url' do - expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.path_with_namespace}/commit/#{note.commit_id}#note_#{note.id}" - end - end - - describe 'When asking for a note on commit diff' do - let(:note) { create(:note_on_commit_diff) } - let(:url) { Gitlab::UrlBuilder.new(:note).build(note.id) } - - it 'returns the note url' do - expect(url).to eq "#{Settings.gitlab['url']}/#{note.project.path_with_namespace}/commit/#{note.commit_id}#note_#{note.id}" - end - end - - describe 'When asking for a note on issue' do - let(:issue) { create(:issue) } - let(:note) { create(:note_on_issue, noteable_id: issue.id) } - let(:url) { Gitlab::UrlBuilder.new(:note).build(note.id) } - - it 'returns the note url' do - expect(url).to eq "#{Settings.gitlab['url']}/#{issue.project.path_with_namespace}/issues/#{issue.iid}#note_#{note.id}" - end - end - - describe 'When asking for a note on merge request' do - let(:merge_request) { create(:merge_request) } - let(:note) { create(:note_on_merge_request, noteable_id: merge_request.id) } - let(:url) { Gitlab::UrlBuilder.new(:note).build(note.id) } - - it 'returns the note url' do - expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}#note_#{note.id}" - end - end - - describe 'When asking for a note on merge request diff' do - let(:merge_request) { create(:merge_request) } - let(:note) { create(:note_on_merge_request_diff, noteable_id: merge_request.id) } - let(:url) { Gitlab::UrlBuilder.new(:note).build(note.id) } - - it 'returns the note url' do - expect(url).to eq "#{Settings.gitlab['url']}/#{merge_request.project.path_with_namespace}/merge_requests/#{merge_request.iid}#note_#{note.id}" - end - end - - describe 'When asking for a note on project snippet' do - let(:snippet) { create(:project_snippet) } - let(:note) { create(:note_on_project_snippet, noteable_id: snippet.id) } - let(:url) { Gitlab::UrlBuilder.new(:note).build(note.id) } - - it 'returns the note url' do - expect(url).to eq "#{Settings.gitlab['url']}/#{snippet.project.path_with_namespace}/snippets/#{note.noteable_id}#note_#{note.id}" - end - end -end diff --git a/spec/lib/gitlab/version_info_spec.rb b/spec/lib/gitlab/version_info_spec.rb deleted file mode 100644 index 5afeb1c1ec3048de7691da7e2f8f0991200b7187..0000000000000000000000000000000000000000 --- a/spec/lib/gitlab/version_info_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'spec_helper' - -describe 'Gitlab::VersionInfo', no_db: true do - before do - @unknown = Gitlab::VersionInfo.new - @v0_0_1 = Gitlab::VersionInfo.new(0, 0, 1) - @v0_1_0 = Gitlab::VersionInfo.new(0, 1, 0) - @v1_0_0 = Gitlab::VersionInfo.new(1, 0, 0) - @v1_0_1 = Gitlab::VersionInfo.new(1, 0, 1) - @v1_1_0 = Gitlab::VersionInfo.new(1, 1, 0) - @v2_0_0 = Gitlab::VersionInfo.new(2, 0, 0) - end - - context '>' do - it { expect(@v2_0_0).to be > @v1_1_0 } - it { expect(@v1_1_0).to be > @v1_0_1 } - it { expect(@v1_0_1).to be > @v1_0_0 } - it { expect(@v1_0_0).to be > @v0_1_0 } - it { expect(@v0_1_0).to be > @v0_0_1 } - end - - context '>=' do - it { expect(@v2_0_0).to be >= Gitlab::VersionInfo.new(2, 0, 0) } - it { expect(@v2_0_0).to be >= @v1_1_0 } - end - - context '<' do - it { expect(@v0_0_1).to be < @v0_1_0 } - it { expect(@v0_1_0).to be < @v1_0_0 } - it { expect(@v1_0_0).to be < @v1_0_1 } - it { expect(@v1_0_1).to be < @v1_1_0 } - it { expect(@v1_1_0).to be < @v2_0_0 } - end - - context '<=' do - it { expect(@v0_0_1).to be <= Gitlab::VersionInfo.new(0, 0, 1) } - it { expect(@v0_0_1).to be <= @v0_1_0 } - end - - context '==' do - it { expect(@v0_0_1).to eq(Gitlab::VersionInfo.new(0, 0, 1)) } - it { expect(@v0_1_0).to eq(Gitlab::VersionInfo.new(0, 1, 0)) } - it { expect(@v1_0_0).to eq(Gitlab::VersionInfo.new(1, 0, 0)) } - end - - context '!=' do - it { expect(@v0_0_1).not_to eq(@v0_1_0) } - end - - context 'unknown' do - it { expect(@unknown).not_to be @v0_0_1 } - it { expect(@unknown).not_to be Gitlab::VersionInfo.new } - it { expect{@unknown > @v0_0_1}.to raise_error(ArgumentError) } - it { expect{@unknown < @v0_0_1}.to raise_error(ArgumentError) } - end - - context 'parse' do - it { expect(Gitlab::VersionInfo.parse("1.0.0")).to eq(@v1_0_0) } - it { expect(Gitlab::VersionInfo.parse("1.0.0.1")).to eq(@v1_0_0) } - it { expect(Gitlab::VersionInfo.parse("git 1.0.0b1")).to eq(@v1_0_0) } - it { expect(Gitlab::VersionInfo.parse("git 1.0b1")).not_to be_valid } - end - - context 'to_s' do - it { expect(@v1_0_0.to_s).to eq("1.0.0") } - it { expect(@unknown.to_s).to eq("Unknown") } - end -end - diff --git a/spec/lib/repository_cache_spec.rb b/spec/lib/repository_cache_spec.rb deleted file mode 100644 index af399f3a7319795710c5052736f1413f2c36baa7..0000000000000000000000000000000000000000 --- a/spec/lib/repository_cache_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'rspec' -require_relative '../../lib/repository_cache' - -describe RepositoryCache do - let(:backend) { double('backend').as_null_object } - let(:cache) { RepositoryCache.new('example', backend) } - - describe '#cache_key' do - it 'includes the namespace' do - expect(cache.cache_key(:foo)).to eq 'foo:example' - end - end - - describe '#expire' do - it 'expires the given key from the cache' do - cache.expire(:foo) - expect(backend).to have_received(:delete).with('foo:example') - end - end - - describe '#fetch' do - it 'fetches the given key from the cache' do - cache.fetch(:bar) - expect(backend).to have_received(:fetch).with('bar:example') - end - - it 'accepts a block' do - p = -> {} - - cache.fetch(:baz, &p) - expect(backend).to have_received(:fetch).with('baz:example', &p) - end - end -end diff --git a/spec/lib/votes_spec.rb b/spec/lib/votes_spec.rb deleted file mode 100644 index df243a26008dca1ab7fafe6907b95d21fc49717a..0000000000000000000000000000000000000000 --- a/spec/lib/votes_spec.rb +++ /dev/null @@ -1,185 +0,0 @@ -require 'spec_helper' - -describe Issue, 'Votes' do - let(:issue) { create(:issue) } - - describe "#upvotes" do - it "with no notes has a 0/0 score" do - expect(issue.upvotes).to eq(0) - end - - it "should recognize non-+1 notes" do - add_note "No +1 here" - expect(issue.notes.size).to eq(1) - expect(issue.notes.first.upvote?).to be_falsey - expect(issue.upvotes).to eq(0) - end - - it "should recognize a single +1 note" do - add_note "+1 This is awesome" - expect(issue.upvotes).to eq(1) - end - - it 'should recognize multiple +1 notes' do - add_note '+1 This is awesome', create(:user) - add_note '+1 I want this', create(:user) - expect(issue.upvotes).to eq(2) - end - - it 'should not count 2 +1 votes from the same user' do - add_note '+1 This is awesome' - add_note '+1 I want this' - expect(issue.upvotes).to eq(1) - end - end - - describe "#downvotes" do - it "with no notes has a 0/0 score" do - expect(issue.downvotes).to eq(0) - end - - it "should recognize non--1 notes" do - add_note "Almost got a -1" - expect(issue.notes.size).to eq(1) - expect(issue.notes.first.downvote?).to be_falsey - expect(issue.downvotes).to eq(0) - end - - it "should recognize a single -1 note" do - add_note "-1 This is bad" - expect(issue.downvotes).to eq(1) - end - - it "should recognize multiple -1 notes" do - add_note('-1 This is bad', create(:user)) - add_note('-1 Away with this', create(:user)) - expect(issue.downvotes).to eq(2) - end - end - - describe "#votes_count" do - it "with no notes has a 0/0 score" do - expect(issue.votes_count).to eq(0) - end - - it "should recognize non notes" do - add_note "No +1 here" - expect(issue.notes.size).to eq(1) - expect(issue.votes_count).to eq(0) - end - - it "should recognize a single +1 note" do - add_note "+1 This is awesome" - expect(issue.votes_count).to eq(1) - end - - it "should recognize a single -1 note" do - add_note "-1 This is bad" - expect(issue.votes_count).to eq(1) - end - - it "should recognize multiple notes" do - add_note('+1 This is awesome', create(:user)) - add_note('-1 This is bad', create(:user)) - add_note('+1 I want this', create(:user)) - expect(issue.votes_count).to eq(3) - end - - it 'should not count 2 -1 votes from the same user' do - add_note '-1 This is suspicious' - add_note '-1 This is bad' - expect(issue.votes_count).to eq(1) - end - end - - describe "#upvotes_in_percent" do - it "with no notes has a 0% score" do - expect(issue.upvotes_in_percent).to eq(0) - end - - it "should count a single 1 note as 100%" do - add_note "+1 This is awesome" - expect(issue.upvotes_in_percent).to eq(100) - end - - it 'should count multiple +1 notes as 100%' do - add_note('+1 This is awesome', create(:user)) - add_note('+1 I want this', create(:user)) - expect(issue.upvotes_in_percent).to eq(100) - end - - it 'should count fractions for multiple +1 and -1 notes correctly' do - add_note('+1 This is awesome', create(:user)) - add_note('+1 I want this', create(:user)) - add_note('-1 This is bad', create(:user)) - add_note('+1 me too', create(:user)) - expect(issue.upvotes_in_percent).to eq(75) - end - end - - describe "#downvotes_in_percent" do - it "with no notes has a 0% score" do - expect(issue.downvotes_in_percent).to eq(0) - end - - it "should count a single -1 note as 100%" do - add_note "-1 This is bad" - expect(issue.downvotes_in_percent).to eq(100) - end - - it 'should count multiple -1 notes as 100%' do - add_note('-1 This is bad', create(:user)) - add_note('-1 Away with this', create(:user)) - expect(issue.downvotes_in_percent).to eq(100) - end - - it 'should count fractions for multiple +1 and -1 notes correctly' do - add_note('+1 This is awesome', create(:user)) - add_note('+1 I want this', create(:user)) - add_note('-1 This is bad', create(:user)) - add_note('+1 me too', create(:user)) - expect(issue.downvotes_in_percent).to eq(25) - end - end - - describe '#filter_superceded_votes' do - - it 'should count a users vote only once amongst multiple votes' do - add_note('-1 This needs work before I will accept it') - add_note('+1 I want this', create(:user)) - add_note('+1 This is is awesome', create(:user)) - add_note('+1 this looks good now') - add_note('+1 This is awesome', create(:user)) - add_note('+1 me too', create(:user)) - expect(issue.downvotes).to eq(0) - expect(issue.upvotes).to eq(5) - end - - it 'should count each users vote only once' do - add_note '-1 This needs work before it will be accepted' - add_note '+1 I like this' - add_note '+1 I still like this' - add_note '+1 I really like this' - add_note '+1 Give me this now!!!!' - expect(issue.downvotes).to eq(0) - expect(issue.upvotes).to eq(1) - end - - it 'should count a users vote only once without caring about comments' do - add_note '-1 This needs work before it will be accepted' - add_note 'Comment 1' - add_note 'Another comment' - add_note '+1 vote' - add_note 'final comment' - expect(issue.downvotes).to eq(0) - expect(issue.upvotes).to eq(1) - end - - end - - def add_note(text, author = issue.author) - created_at = Time.now - 1.hour + Note.count.seconds - issue.notes << create(:note, note: text, project: issue.project, - author_id: author.id, created_at: created_at) - end -end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb deleted file mode 100644 index b297fbd51192f49354ef8f0dc391be9461c6e2c1..0000000000000000000000000000000000000000 --- a/spec/mailers/notify_spec.rb +++ /dev/null @@ -1,808 +0,0 @@ -require 'spec_helper' - -describe Notify do - include EmailSpec::Helpers - include EmailSpec::Matchers - include RepoHelpers - - let(:gitlab_sender_display_name) { Gitlab.config.gitlab.email_display_name } - let(:gitlab_sender) { Gitlab.config.gitlab.email_from } - let(:gitlab_sender_reply_to) { Gitlab.config.gitlab.email_reply_to } - let(:recipient) { create(:user, email: 'recipient@example.com') } - let(:project) { create(:project) } - - around(:each) { ActionMailer::Base.deliveries.clear } - - before(:each) do - email = recipient.emails.create(email: "notifications@example.com") - recipient.update_attribute(:notification_email, email.email) - end - - shared_examples 'a multiple recipients email' do - it 'is sent to the given recipient' do - is_expected.to deliver_to recipient.notification_email - end - end - - shared_examples 'an email sent from GitLab' do - it 'is sent from GitLab' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(gitlab_sender_display_name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'has a Reply-To address' do - reply_to = subject.header[:reply_to].addresses - expect(reply_to).to eq([gitlab_sender_reply_to]) - end - end - - shared_examples 'an email starting a new thread' do |message_id_prefix| - it 'has a discussion identifier' do - is_expected.to have_header 'Message-ID', /<#{message_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/ - is_expected.to have_header 'X-GitLab-Project', /#{project.name}/ - end - end - - shared_examples 'an answer to an existing thread' do |thread_id_prefix| - it 'has a subject that begins with Re: ' do - is_expected.to have_subject /^Re: / - end - - it 'has headers that reference an existing thread' do - is_expected.to have_header 'References', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/ - is_expected.to have_header 'In-Reply-To', /<#{thread_id_prefix}(.*)@#{Gitlab.config.gitlab.host}>/ - is_expected.to have_header 'X-GitLab-Project', /#{project.name}/ - end - end - - describe 'for new users, the email' do - let(:example_site_path) { root_path } - let(:new_user) { create(:user, email: 'newguy@example.com', created_by_id: 1) } - - token = 'kETLwRaayvigPq_x3SNM' - - subject { Notify.new_user_email(new_user.id, token) } - - it_behaves_like 'an email sent from GitLab' - - it 'is sent to the new user' do - is_expected.to deliver_to new_user.email - end - - it 'has the correct subject' do - is_expected.to have_subject /^Account was created for you$/i - end - - it 'contains the new user\'s login name' do - is_expected.to have_body_text /#{new_user.email}/ - end - - it 'contains the password text' do - is_expected.to have_body_text /Click here to set your password/ - end - - it 'includes a link for user to set password' do - params = "reset_password_token=#{token}" - is_expected.to have_body_text( - %r{http://localhost(:\d+)?/users/password/edit\?#{params}} - ) - end - - it 'includes a link to the site' do - is_expected.to have_body_text /#{example_site_path}/ - end - end - - - describe 'for users that signed up, the email' do - let(:example_site_path) { root_path } - let(:new_user) { create(:user, email: 'newguy@example.com', password: "securePassword") } - - subject { Notify.new_user_email(new_user.id) } - - it_behaves_like 'an email sent from GitLab' - - it 'is sent to the new user' do - is_expected.to deliver_to new_user.email - end - - it 'has the correct subject' do - is_expected.to have_subject /^Account was created for you$/i - end - - it 'contains the new user\'s login name' do - is_expected.to have_body_text /#{new_user.email}/ - end - - it 'should not contain the new user\'s password' do - is_expected.not_to have_body_text /password/ - end - - it 'includes a link to the site' do - is_expected.to have_body_text /#{example_site_path}/ - end - end - - describe 'user added ssh key' do - let(:key) { create(:personal_key) } - - subject { Notify.new_ssh_key_email(key.id) } - - it_behaves_like 'an email sent from GitLab' - - it 'is sent to the new user' do - is_expected.to deliver_to key.user.email - end - - it 'has the correct subject' do - is_expected.to have_subject /^SSH key was added to your account$/i - end - - it 'contains the new ssh key title' do - is_expected.to have_body_text /#{key.title}/ - end - - it 'includes a link to ssh keys page' do - is_expected.to have_body_text /#{profile_keys_path}/ - end - end - - describe 'user added email' do - let(:email) { create(:email) } - - subject { Notify.new_email_email(email.id) } - - it 'is sent to the new user' do - is_expected.to deliver_to email.user.email - end - - it 'has the correct subject' do - is_expected.to have_subject /^Email was added to your account$/i - end - - it 'contains the new email address' do - is_expected.to have_body_text /#{email.email}/ - end - - it 'includes a link to emails page' do - is_expected.to have_body_text /#{profile_emails_path}/ - end - end - - context 'for a project' do - describe 'items that are assignable, the email' do - let(:current_user) { create(:user, email: "current@email.com") } - let(:assignee) { create(:user, email: 'assignee@example.com') } - let(:previous_assignee) { create(:user, name: 'Previous Assignee') } - - shared_examples 'an assignee email' do - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(current_user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'is sent to the assignee' do - is_expected.to deliver_to assignee.email - end - end - - context 'for issues' do - let(:issue) { create(:issue, author: current_user, assignee: assignee, project: project) } - let(:issue_with_description) { create(:issue, author: current_user, assignee: assignee, project: project, description: Faker::Lorem.sentence) } - - describe 'that are new' do - subject { Notify.new_issue_email(issue.assignee_id, issue.id) } - - it_behaves_like 'an assignee email' - it_behaves_like 'an email starting a new thread', 'issue' - - it 'has the correct subject' do - is_expected.to have_subject /#{project.name} \| #{issue.title} \(##{issue.iid}\)/ - end - - it 'contains a link to the new issue' do - is_expected.to have_body_text /#{namespace_project_issue_path project.namespace, project, issue}/ - end - end - - describe 'that are new with a description' do - subject { Notify.new_issue_email(issue_with_description.assignee_id, issue_with_description.id) } - - it 'contains the description' do - is_expected.to have_body_text /#{issue_with_description.description}/ - end - end - - describe 'that have been reassigned' do - subject { Notify.reassigned_issue_email(recipient.id, issue.id, previous_assignee.id, current_user) } - - it_behaves_like 'a multiple recipients email' - it_behaves_like 'an answer to an existing thread', 'issue' - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(current_user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'has the correct subject' do - is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/ - end - - it 'contains the name of the previous assignee' do - is_expected.to have_body_text /#{previous_assignee.name}/ - end - - it 'contains the name of the new assignee' do - is_expected.to have_body_text /#{assignee.name}/ - end - - it 'contains a link to the issue' do - is_expected.to have_body_text /#{namespace_project_issue_path project.namespace, project, issue}/ - end - end - - describe 'status changed' do - let(:status) { 'closed' } - subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) } - - it_behaves_like 'an answer to an existing thread', 'issue' - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(current_user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'has the correct subject' do - is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/i - end - - it 'contains the new status' do - is_expected.to have_body_text /#{status}/i - end - - it 'contains the user name' do - is_expected.to have_body_text /#{current_user.name}/i - end - - it 'contains a link to the issue' do - is_expected.to have_body_text /#{namespace_project_issue_path project.namespace, project, issue}/ - end - end - - end - - context 'for merge requests' do - let(:merge_author) { create(:user) } - let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) } - let(:merge_request_with_description) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project, description: Faker::Lorem.sentence) } - - describe 'that are new' do - subject { Notify.new_merge_request_email(merge_request.assignee_id, merge_request.id) } - - it_behaves_like 'an assignee email' - it_behaves_like 'an email starting a new thread', 'merge_request' - - it 'has the correct subject' do - is_expected.to have_subject /#{merge_request.title} \(##{merge_request.iid}\)/ - end - - it 'contains a link to the new merge request' do - is_expected.to have_body_text /#{namespace_project_merge_request_path(project.namespace, project, merge_request)}/ - end - - it 'contains the source branch for the merge request' do - is_expected.to have_body_text /#{merge_request.source_branch}/ - end - - it 'contains the target branch for the merge request' do - is_expected.to have_body_text /#{merge_request.target_branch}/ - end - - it 'has the correct message-id set' do - is_expected.to have_header 'Message-ID', "" - end - end - - describe 'that are new with a description' do - subject { Notify.new_merge_request_email(merge_request_with_description.assignee_id, merge_request_with_description.id) } - - it 'contains the description' do - is_expected.to have_body_text /#{merge_request_with_description.description}/ - end - end - - describe 'that are reassigned' do - subject { Notify.reassigned_merge_request_email(recipient.id, merge_request.id, previous_assignee.id, current_user.id) } - - it_behaves_like 'a multiple recipients email' - it_behaves_like 'an answer to an existing thread', 'merge_request' - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(current_user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'has the correct subject' do - is_expected.to have_subject /#{merge_request.title} \(##{merge_request.iid}\)/ - end - - it 'contains the name of the previous assignee' do - is_expected.to have_body_text /#{previous_assignee.name}/ - end - - it 'contains the name of the new assignee' do - is_expected.to have_body_text /#{assignee.name}/ - end - - it 'contains a link to the merge request' do - is_expected.to have_body_text /#{namespace_project_merge_request_path project.namespace, project, merge_request}/ - end - end - - describe 'status changed' do - let(:status) { 'reopened' } - subject { Notify.merge_request_status_email(recipient.id, merge_request.id, status, current_user) } - - it_behaves_like 'an answer to an existing thread', 'merge_request' - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(current_user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'has the correct subject' do - is_expected.to have_subject /#{merge_request.title} \(##{merge_request.iid}\)/i - end - - it 'contains the new status' do - is_expected.to have_body_text /#{status}/i - end - - it 'contains the user name' do - is_expected.to have_body_text /#{current_user.name}/i - end - - it 'contains a link to the merge request' do - is_expected.to have_body_text /#{namespace_project_merge_request_path project.namespace, project, merge_request}/ - end - end - - describe 'that are merged' do - subject { Notify.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) } - - it_behaves_like 'a multiple recipients email' - it_behaves_like 'an answer to an existing thread', 'merge_request' - - it 'is sent as the merge author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(merge_author.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'has the correct subject' do - is_expected.to have_subject /#{merge_request.title} \(##{merge_request.iid}\)/ - end - - it 'contains the new status' do - is_expected.to have_body_text /merged/i - end - - it 'contains a link to the merge request' do - is_expected.to have_body_text /#{namespace_project_merge_request_path project.namespace, project, merge_request}/ - end - end - end - end - - describe 'project was moved' do - let(:project) { create(:project) } - let(:user) { create(:user) } - subject { Notify.project_was_moved_email(project.id, user.id) } - - it_behaves_like 'an email sent from GitLab' - - it 'has the correct subject' do - is_expected.to have_subject /Project was moved/ - end - - it 'contains name of project' do - is_expected.to have_body_text /#{project.name_with_namespace}/ - end - - it 'contains new user role' do - is_expected.to have_body_text /#{project.ssh_url_to_repo}/ - end - end - - describe 'project access changed' do - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:project_member) { create(:project_member, - project: project, - user: user) } - subject { Notify.project_access_granted_email(project_member.id) } - - it_behaves_like 'an email sent from GitLab' - - it 'has the correct subject' do - is_expected.to have_subject /Access to project was granted/ - end - it 'contains name of project' do - is_expected.to have_body_text /#{project.name}/ - end - it 'contains new user role' do - is_expected.to have_body_text /#{project_member.human_access}/ - end - end - - context 'items that are noteable, the email for a note' do - let(:note_author) { create(:user, name: 'author_name') } - let(:note) { create(:note, project: project, author: note_author) } - - before :each do - allow(Note).to receive(:find).with(note.id).and_return(note) - end - - shared_examples 'a note email' do - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(note_author.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'is sent to the given recipient' do - is_expected.to deliver_to recipient.notification_email - end - - it 'contains the message from the note' do - is_expected.to have_body_text /#{note.note}/ - end - end - - describe 'on a commit' do - let(:commit) { project.repository.commit } - - before(:each) { allow(note).to receive(:noteable).and_return(commit) } - - subject { Notify.note_commit_email(recipient.id, note.id) } - - it_behaves_like 'a note email' - it_behaves_like 'an answer to an existing thread', 'commits' - - it 'has the correct subject' do - is_expected.to have_subject /#{commit.title} \(#{commit.short_id}\)/ - end - - it 'contains a link to the commit' do - is_expected.to have_body_text commit.short_id - end - end - - describe 'on a merge request' do - let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let(:note_on_merge_request_path) { namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: "note_#{note.id}") } - before(:each) { allow(note).to receive(:noteable).and_return(merge_request) } - - subject { Notify.note_merge_request_email(recipient.id, note.id) } - - it_behaves_like 'a note email' - it_behaves_like 'an answer to an existing thread', 'merge_request' - - it 'has the correct subject' do - is_expected.to have_subject /#{merge_request.title} \(##{merge_request.iid}\)/ - end - - it 'contains a link to the merge request note' do - is_expected.to have_body_text /#{note_on_merge_request_path}/ - end - end - - describe 'on an issue' do - let(:issue) { create(:issue, project: project) } - let(:note_on_issue_path) { namespace_project_issue_path(project.namespace, project, issue, anchor: "note_#{note.id}") } - before(:each) { allow(note).to receive(:noteable).and_return(issue) } - - subject { Notify.note_issue_email(recipient.id, note.id) } - - it_behaves_like 'a note email' - it_behaves_like 'an answer to an existing thread', 'issue' - - it 'has the correct subject' do - is_expected.to have_subject /#{issue.title} \(##{issue.iid}\)/ - end - - it 'contains a link to the issue note' do - is_expected.to have_body_text /#{note_on_issue_path}/ - end - end - end - end - - describe 'group access changed' do - let(:group) { create(:group) } - let(:user) { create(:user) } - let(:membership) { create(:group_member, group: group, user: user) } - - subject { Notify.group_access_granted_email(membership.id) } - - it_behaves_like 'an email sent from GitLab' - - it 'has the correct subject' do - is_expected.to have_subject /Access to group was granted/ - end - - it 'contains name of project' do - is_expected.to have_body_text /#{group.name}/ - end - - it 'contains new user role' do - is_expected.to have_body_text /#{membership.human_access}/ - end - end - - describe 'confirmation if email changed' do - let(:example_site_path) { root_path } - let(:user) { create(:user, email: 'old-email@mail.com') } - - before do - user.email = "new-email@mail.com" - user.save - end - - subject { ActionMailer::Base.deliveries.last } - - it_behaves_like 'an email sent from GitLab' - - it 'is sent to the new user' do - is_expected.to deliver_to 'new-email@mail.com' - end - - it 'has the correct subject' do - is_expected.to have_subject "Confirmation instructions" - end - - it 'includes a link to the site' do - is_expected.to have_body_text /#{example_site_path}/ - end - end - - describe 'email on push for a created branch' do - let(:example_site_path) { root_path } - let(:user) { create(:user) } - let(:tree_path) { namespace_project_tree_path(project.namespace, project, "master") } - - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :create) } - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - - it 'has the correct subject' do - is_expected.to have_subject /Pushed new branch master/ - end - - it 'contains a link to the branch' do - is_expected.to have_body_text /#{tree_path}/ - end - end - - describe 'email on push for a created tag' do - let(:example_site_path) { root_path } - let(:user) { create(:user) } - let(:tree_path) { namespace_project_tree_path(project.namespace, project, "v1.0") } - - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/tags/v1.0', action: :create) } - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - - it 'has the correct subject' do - is_expected.to have_subject /Pushed new tag v1\.0/ - end - - it 'contains a link to the tag' do - is_expected.to have_body_text /#{tree_path}/ - end - end - - describe 'email on push for a deleted branch' do - let(:example_site_path) { root_path } - let(:user) { create(:user) } - - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :delete) } - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - - it 'has the correct subject' do - is_expected.to have_subject /Deleted branch master/ - end - end - - describe 'email on push for a deleted tag' do - let(:example_site_path) { root_path } - let(:user) { create(:user) } - - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/tags/v1.0', action: :delete) } - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - - it 'has the correct subject' do - is_expected.to have_subject /Deleted tag v1\.0/ - end - end - - describe 'email on push with multiple commits' do - let(:example_site_path) { root_path } - let(:user) { create(:user) } - let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) } - let(:commits) { Commit.decorate(compare.commits) } - let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base), to: Commit.new(compare.head)) } - let(:send_from_committer_email) { false } - - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, reverse_compare: false, send_from_committer_email: send_from_committer_email) } - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - - it 'has the correct subject' do - is_expected.to have_subject /\[#{project.path_with_namespace}\]\[master\] #{commits.length} commits:/ - end - - it 'includes commits list' do - is_expected.to have_body_text /Change some files/ - end - - it 'includes diffs' do - is_expected.to have_body_text /def archive_formats_regex/ - end - - it 'contains a link to the diff' do - is_expected.to have_body_text /#{diff_path}/ - end - - it 'doesn not contain the misleading footer' do - is_expected.not_to have_body_text /you are a member of/ - end - - context "when set to send from committer email if domain matches" do - - let(:send_from_committer_email) { true } - - before do - allow(Gitlab.config.gitlab).to receive(:host).and_return("gitlab.corp.company.com") - end - - context "when the committer email domain is within the GitLab domain" do - - before do - user.update_attribute(:email, "user@company.com") - user.confirm! - end - - it "is sent from the committer email" do - sender = subject.header[:from].addrs[0] - expect(sender.address).to eq(user.email) - end - - it "is set to reply to the committer email" do - sender = subject.header[:reply_to].addrs[0] - expect(sender.address).to eq(user.email) - end - end - - context "when the committer email domain is not completely within the GitLab domain" do - - before do - user.update_attribute(:email, "user@something.company.com") - user.confirm! - end - - it "is sent from the default email" do - sender = subject.header[:from].addrs[0] - expect(sender.address).to eq(gitlab_sender) - end - - it "is set to reply to the default email" do - sender = subject.header[:reply_to].addrs[0] - expect(sender.address).to eq(gitlab_sender_reply_to) - end - end - - context "when the committer email domain is outside the GitLab domain" do - - before do - user.update_attribute(:email, "user@mpany.com") - user.confirm! - end - - it "is sent from the default email" do - sender = subject.header[:from].addrs[0] - expect(sender.address).to eq(gitlab_sender) - end - - it "is set to reply to the default email" do - sender = subject.header[:reply_to].addrs[0] - expect(sender.address).to eq(gitlab_sender_reply_to) - end - end - end - end - - describe 'email on push with a single commit' do - let(:example_site_path) { root_path } - let(:user) { create(:user) } - let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) } - let(:commits) { Commit.decorate(compare.commits) } - let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) } - - subject { Notify.repository_push_email(project.id, 'devs@company.name', author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare) } - - it 'is sent as the author' do - sender = subject.header[:from].addrs[0] - expect(sender.display_name).to eq(user.name) - expect(sender.address).to eq(gitlab_sender) - end - - it 'is sent to recipient' do - is_expected.to deliver_to 'devs@company.name' - end - - it 'has the correct subject' do - is_expected.to have_subject /#{commits.first.title}/ - end - - it 'includes commits list' do - is_expected.to have_body_text /Change some files/ - end - - it 'includes diffs' do - is_expected.to have_body_text /def archive_formats_regex/ - end - - it 'contains a link to the diff' do - is_expected.to have_body_text /#{diff_path}/ - end - end -end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb deleted file mode 100644 index b4f0b2c201aba6f638f0a3d6762a0efd9c1dff25..0000000000000000000000000000000000000000 --- a/spec/models/application_setting_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# == Schema Information -# -# Table name: application_settings -# -# id :integer not null, primary key -# default_projects_limit :integer -# default_branch_protection :integer -# signup_enabled :boolean -# signin_enabled :boolean -# gravatar_enabled :boolean -# sign_in_text :text -# created_at :datetime -# updated_at :datetime -# home_page_url :string(255) -# default_branch_protection :integer default(2) -# twitter_sharing_enabled :boolean default(TRUE) -# restricted_visibility_levels :text -# - -require 'spec_helper' - -describe ApplicationSetting, models: true do - it { expect(ApplicationSetting.create_from_defaults).to be_valid } -end diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb deleted file mode 100644 index 8ab72151a690b1e37b60cffe94e0742955907f48..0000000000000000000000000000000000000000 --- a/spec/models/broadcast_message_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# == Schema Information -# -# Table name: broadcast_messages -# -# id :integer not null, primary key -# message :text not null -# starts_at :datetime -# ends_at :datetime -# alert_type :integer -# created_at :datetime -# updated_at :datetime -# color :string(255) -# font :string(255) -# - -require 'spec_helper' - -describe BroadcastMessage do - subject { create(:broadcast_message) } - - it { is_expected.to be_valid } - - describe :current do - it "should return last message if time match" do - broadcast_message = create(:broadcast_message, starts_at: Time.now.yesterday, ends_at: Time.now.tomorrow) - expect(BroadcastMessage.current).to eq(broadcast_message) - end - - it "should return nil if time not come" do - broadcast_message = create(:broadcast_message, starts_at: Time.now.tomorrow, ends_at: Time.now + 2.days) - expect(BroadcastMessage.current).to be_nil - end - - it "should return nil if time has passed" do - broadcast_message = create(:broadcast_message, starts_at: Time.now - 2.days, ends_at: Time.now.yesterday) - expect(BroadcastMessage.current).to be_nil - end - end -end diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb deleted file mode 100644 index 11cc7762ce4353dda61599129193b0678fb8b282..0000000000000000000000000000000000000000 --- a/spec/models/commit_spec.rb +++ /dev/null @@ -1,80 +0,0 @@ -require 'spec_helper' - -describe Commit do - let(:project) { create :project } - let(:commit) { project.repository.commit } - - describe '#title' do - it "returns no_commit_message when safe_message is blank" do - allow(commit).to receive(:safe_message).and_return('') - expect(commit.title).to eq("--no commit message") - end - - it "truncates a message without a newline at 80 characters" do - message = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales id felis id blandit. Vivamus egestas lacinia lacus, sed rutrum mauris.' - - allow(commit).to receive(:safe_message).and_return(message) - expect(commit.title).to eq("#{message[0..79]}…") - end - - it "truncates a message with a newline before 80 characters at the newline" do - message = commit.safe_message.split(" ").first - - allow(commit).to receive(:safe_message).and_return(message + "\n" + message) - expect(commit.title).to eq(message) - end - - it "does not truncates a message with a newline after 80 but less 100 characters" do - message =<(txt){ subject.stub(safe_message: txt) } } - - # Include the subject in the repository stub. - let(:extra_commits) { [subject] } - end -end diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb deleted file mode 100644 index 557c71b4d2cecc2c8a28f2a57633fee4ef7051f3..0000000000000000000000000000000000000000 --- a/spec/models/concerns/issuable_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -require 'spec_helper' - -describe Issue, "Issuable" do - let(:issue) { create(:issue) } - - describe "Associations" do - it { is_expected.to belong_to(:project) } - it { is_expected.to belong_to(:author) } - it { is_expected.to belong_to(:assignee) } - it { is_expected.to have_many(:notes).dependent(:destroy) } - end - - describe "Validation" do - before { subject.stub(set_iid: false) } - it { is_expected.to validate_presence_of(:project) } - it { is_expected.to validate_presence_of(:iid) } - it { is_expected.to validate_presence_of(:author) } - it { is_expected.to validate_presence_of(:title) } - it { is_expected.to ensure_length_of(:title).is_at_least(0).is_at_most(255) } - end - - describe "Scope" do - it { expect(described_class).to respond_to(:opened) } - it { expect(described_class).to respond_to(:closed) } - it { expect(described_class).to respond_to(:assigned) } - end - - describe ".search" do - let!(:searchable_issue) { create(:issue, title: "Searchable issue") } - - it "matches by title" do - expect(described_class.search('able')).to eq([searchable_issue]) - end - end - - describe "#today?" do - it "returns true when created today" do - # Avoid timezone differences and just return exactly what we want - allow(Date).to receive(:today).and_return(issue.created_at.to_date) - expect(issue.today?).to be_truthy - end - - it "returns false when not created today" do - allow(Date).to receive(:today).and_return(Date.yesterday) - expect(issue.today?).to be_falsey - end - end - - describe "#new?" do - it "returns true when created today and record hasn't been updated" do - allow(issue).to receive(:today?).and_return(true) - expect(issue.new?).to be_truthy - end - - it "returns false when not created today" do - allow(issue).to receive(:today?).and_return(false) - expect(issue.new?).to be_falsey - end - - it "returns false when record has been updated" do - allow(issue).to receive(:today?).and_return(true) - issue.touch - expect(issue.new?).to be_falsey - end - end -end diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb deleted file mode 100644 index eadb941a3fa8780eb5789e890760c9661295c89d..0000000000000000000000000000000000000000 --- a/spec/models/concerns/mentionable_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'spec_helper' - -describe Issue, "Mentionable" do - describe :mentioned_users do - let!(:user) { create(:user, username: 'stranger') } - let!(:user2) { create(:user, username: 'john') } - let!(:issue) { create(:issue, description: '@stranger mentioned') } - - subject { issue.mentioned_users } - - it { is_expected.to include(user) } - it { is_expected.not_to include(user2) } - end -end diff --git a/spec/models/deploy_key_spec.rb b/spec/models/deploy_key_spec.rb deleted file mode 100644 index b32be8d7a7cb45199703192cf0c8d2f4fbcd8d55..0000000000000000000000000000000000000000 --- a/spec/models/deploy_key_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime -# updated_at :datetime -# key :text -# title :string(255) -# type :string(255) -# fingerprint :string(255) -# - -require 'spec_helper' - -describe DeployKey do - let(:project) { create(:project) } - let(:deploy_key) { create(:deploy_key, projects: [project]) } - - describe "Associations" do - it { is_expected.to have_many(:deploy_keys_projects) } - it { is_expected.to have_many(:projects) } - end -end diff --git a/spec/models/deploy_keys_project_spec.rb b/spec/models/deploy_keys_project_spec.rb deleted file mode 100644 index 7032b777144d4d519e92a3ec3d620a3176c5c682..0000000000000000000000000000000000000000 --- a/spec/models/deploy_keys_project_spec.rb +++ /dev/null @@ -1,72 +0,0 @@ -# == Schema Information -# -# Table name: deploy_keys_projects -# -# id :integer not null, primary key -# deploy_key_id :integer not null -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - -require 'spec_helper' - -describe DeployKeysProject do - describe "Associations" do - it { is_expected.to belong_to(:deploy_key) } - it { is_expected.to belong_to(:project) } - end - - describe "Validation" do - it { is_expected.to validate_presence_of(:project_id) } - it { is_expected.to validate_presence_of(:deploy_key_id) } - end - - describe "Destroying" do - let(:project) { create(:project) } - subject { create(:deploy_keys_project, project: project) } - let(:deploy_key) { subject.deploy_key } - - context "when the deploy key is only used by this project" do - context "when the deploy key is public" do - before do - deploy_key.update_attribute(:public, true) - end - - it "doesn't destroy the deploy key" do - subject.destroy - - expect { - deploy_key.reload - }.not_to raise_error(ActiveRecord::RecordNotFound) - end - end - - context "when the deploy key is private" do - it "destroys the deploy key" do - subject.destroy - - expect { - deploy_key.reload - }.to raise_error(ActiveRecord::RecordNotFound) - end - end - end - - context "when the deploy key is used by more than one project" do - let!(:other_project) { create(:project) } - - before do - other_project.deploy_keys << deploy_key - end - - it "doesn't destroy the deploy key" do - subject.destroy - - expect { - deploy_key.reload - }.not_to raise_error(ActiveRecord::RecordNotFound) - end - end - end -end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb deleted file mode 100644 index 0f32f162a104b70ff3d124b0cf9fcece128b6b94..0000000000000000000000000000000000000000 --- a/spec/models/event_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -# == Schema Information -# -# Table name: events -# -# id :integer not null, primary key -# target_type :string(255) -# target_id :integer -# title :string(255) -# data :text -# project_id :integer -# created_at :datetime -# updated_at :datetime -# action :integer -# author_id :integer -# - -require 'spec_helper' - -describe Event do - describe "Associations" do - it { is_expected.to belong_to(:project) } - it { is_expected.to belong_to(:target) } - end - - describe "Respond to" do - it { is_expected.to respond_to(:author_name) } - it { is_expected.to respond_to(:author_email) } - it { is_expected.to respond_to(:issue_title) } - it { is_expected.to respond_to(:merge_request_title) } - it { is_expected.to respond_to(:commits) } - end - - describe "Push event" do - before do - project = create(:project) - @user = project.owner - - data = { - before: Gitlab::Git::BLANK_SHA, - after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", - ref: "refs/heads/master", - user_id: @user.id, - user_name: @user.name, - repository: { - name: project.name, - url: "localhost/rubinius", - description: "", - homepage: "localhost/rubinius", - private: true - } - } - - @event = Event.create( - project: project, - action: Event::PUSHED, - data: data, - author_id: @user.id - ) - end - - it { expect(@event.push?).to be_truthy } - it { expect(@event.proper?).to be_truthy } - it { expect(@event.tag?).to be_falsey } - it { expect(@event.branch_name).to eq("master") } - it { expect(@event.author).to eq(@user) } - end -end diff --git a/spec/models/external_wiki_service_spec.rb b/spec/models/external_wiki_service_spec.rb deleted file mode 100644 index 78ef687d29cbeec644b45d8cc267e782939ae802..0000000000000000000000000000000000000000 --- a/spec/models/external_wiki_service_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'spec_helper' - -describe ExternalWikiService do - include ExternalWikiHelper - describe "Associations" do - it { should belong_to :project } - it { should have_one :service_hook } - end - - describe "Validations" do - context "active" do - before do - subject.active = true - end - - it { should validate_presence_of :external_wiki_url } - end - end - - describe 'External wiki' do - let(:project) { create(:project) } - - context 'when it is active' do - before do - properties = { 'external_wiki_url' => 'https://gitlab.com' } - @service = project.create_external_wiki_service(active: true, properties: properties) - end - - after do - @service.destroy! - end - - it 'should replace the wiki url' do - wiki_path = get_project_wiki_path(project) - wiki_path.should match('https://gitlab.com') - end - end - end -end diff --git a/spec/models/forked_project_link_spec.rb b/spec/models/forked_project_link_spec.rb deleted file mode 100644 index 7d0ad44a92c2ad1f4c072d6c3bc4bc81df6d3097..0000000000000000000000000000000000000000 --- a/spec/models/forked_project_link_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -# == Schema Information -# -# Table name: forked_project_links -# -# id :integer not null, primary key -# forked_to_project_id :integer not null -# forked_from_project_id :integer not null -# created_at :datetime -# updated_at :datetime -# - -require 'spec_helper' - -describe ForkedProjectLink, "add link on fork" do - let(:project_from) { create(:project) } - let(:namespace) { create(:namespace) } - let(:user) { create(:user, namespace: namespace) } - - before do - @project_to = fork_project(project_from, user) - end - - it "project_to should know it is forked" do - expect(@project_to.forked?).to be_truthy - end - - it "project should know who it is forked from" do - expect(@project_to.forked_from_project).to eq(project_from) - end -end - -describe :forked_from_project do - let(:forked_project_link) { build(:forked_project_link) } - let(:project_from) { create(:project) } - let(:project_to) { create(:project, forked_project_link: forked_project_link) } - - - before :each do - forked_project_link.forked_from_project = project_from - forked_project_link.forked_to_project = project_to - forked_project_link.save! - end - - - it "project_to should know it is forked" do - expect(project_to.forked?).to be_truthy - end - - it "project_from should not be forked" do - expect(project_from.forked?).to be_falsey - end - - it "project_to.destroy should destroy fork_link" do - expect(forked_project_link).to receive(:destroy) - project_to.destroy - end - -end - -def fork_project(from_project, user) - context = Projects::ForkService.new(from_project, user) - shell = double("gitlab_shell") - shell.stub(fork_repository: true) - context.stub(gitlab_shell: shell) - context.execute -end - diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb deleted file mode 100644 index 9428224a64f9eba52a98ba773663002d1f4b3c0c..0000000000000000000000000000000000000000 --- a/spec/models/group_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -# == Schema Information -# -# Table name: namespaces -# -# id :integer not null, primary key -# name :string(255) not null -# path :string(255) not null -# owner_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) -# description :string(255) default(""), not null -# avatar :string(255) -# - -require 'spec_helper' - -describe Group do - let!(:group) { create(:group) } - - describe "Associations" do - it { is_expected.to have_many :projects } - it { is_expected.to have_many :group_members } - end - - it { is_expected.to validate_presence_of :name } - it { is_expected.to validate_uniqueness_of(:name) } - it { is_expected.to validate_presence_of :path } - it { is_expected.to validate_uniqueness_of(:path) } - it { is_expected.not_to validate_presence_of :owner } - - describe :users do - it { expect(group.users).to eq(group.owners) } - end - - describe :human_name do - it { expect(group.human_name).to eq(group.name) } - end - - describe :add_users do - let(:user) { create(:user) } - before { group.add_user(user, GroupMember::MASTER) } - - it { expect(group.group_members.masters.map(&:user)).to include(user) } - end - - describe :add_users do - let(:user) { create(:user) } - before { group.add_users([user.id], GroupMember::GUEST) } - - it "should update the group permission" do - expect(group.group_members.guests.map(&:user)).to include(user) - group.add_users([user.id], GroupMember::DEVELOPER) - expect(group.group_members.developers.map(&:user)).to include(user) - expect(group.group_members.guests.map(&:user)).not_to include(user) - end - end - - describe :avatar_type do - let(:user) { create(:user) } - before { group.add_user(user, GroupMember::MASTER) } - - it "should be true if avatar is image" do - group.update_attribute(:avatar, 'uploads/avatar.png') - expect(group.avatar_type).to be_truthy - end - - it "should be false if avatar is html page" do - group.update_attribute(:avatar, 'uploads/avatar.html') - expect(group.avatar_type).to eq(["only images allowed"]) - end - end -end diff --git a/spec/models/hooks/project_hook_spec.rb b/spec/models/hooks/project_hook_spec.rb deleted file mode 100644 index 4e0d50d7f3f6ec1d273b807235ae605d6c2013c4..0000000000000000000000000000000000000000 --- a/spec/models/hooks/project_hook_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# - -require 'spec_helper' - -describe ProjectHook do - describe '.push_hooks' do - it 'should return hooks for push events only' do - hook = create(:project_hook, push_events: true) - hook2 = create(:project_hook, push_events: false) - expect(ProjectHook.push_hooks).to eq([hook]) - end - end - - describe '.tag_push_hooks' do - it 'should return hooks for tag push events only' do - hook = create(:project_hook, tag_push_events: true) - hook2 = create(:project_hook, tag_push_events: false) - expect(ProjectHook.tag_push_hooks).to eq([hook]) - end - end -end diff --git a/spec/models/hooks/service_hook_spec.rb b/spec/models/hooks/service_hook_spec.rb deleted file mode 100644 index 96bf74d45da7589495953ae9ca71598c8cd0d66d..0000000000000000000000000000000000000000 --- a/spec/models/hooks/service_hook_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# - -require "spec_helper" - -describe ServiceHook do - describe "Associations" do - it { is_expected.to belong_to :service } - end -end diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb deleted file mode 100644 index 810b311a40bbc24d60af228bf9a4aa57ec34d375..0000000000000000000000000000000000000000 --- a/spec/models/hooks/system_hook_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# - -require "spec_helper" - -describe SystemHook do - describe "execute" do - before(:each) do - @system_hook = create(:system_hook) - WebMock.stub_request(:post, @system_hook.url) - end - - it "project_create hook" do - Projects::CreateService.new(create(:user), name: 'empty').execute - expect(WebMock).to have_requested(:post, @system_hook.url).with(body: /project_create/).once - end - - it "project_destroy hook" do - user = create(:user) - project = create(:empty_project, namespace: user.namespace) - Projects::DestroyService.new(project, user, {}).execute - expect(WebMock).to have_requested(:post, @system_hook.url).with(body: /project_destroy/).once - end - - it "user_create hook" do - create(:user) - expect(WebMock).to have_requested(:post, @system_hook.url).with(body: /user_create/).once - end - - it "user_destroy hook" do - user = create(:user) - user.destroy - expect(WebMock).to have_requested(:post, @system_hook.url).with(body: /user_destroy/).once - end - - it "project_create hook" do - user = create(:user) - project = create(:project) - project.team << [user, :master] - expect(WebMock).to have_requested(:post, @system_hook.url).with(body: /user_add_to_team/).once - end - - it "project_destroy hook" do - user = create(:user) - project = create(:project) - project.team << [user, :master] - project.project_members.destroy_all - expect(WebMock).to have_requested(:post, @system_hook.url).with(body: /user_remove_from_team/).once - end - - it 'group create hook' do - create(:group) - expect(WebMock).to have_requested(:post, @system_hook.url).with( - body: /group_create/ - ).once - end - - it 'group destroy hook' do - group = create(:group) - group.destroy - expect(WebMock).to have_requested(:post, @system_hook.url).with( - body: /group_destroy/ - ).once - end - - it 'group member create hook' do - group = create(:group) - user = create(:user) - group.add_user(user, Gitlab::Access::MASTER) - expect(WebMock).to have_requested(:post, @system_hook.url).with( - body: /user_add_to_group/ - ).once - end - - it 'group member destroy hook' do - group = create(:group) - user = create(:user) - group.add_user(user, Gitlab::Access::MASTER) - group.group_members.destroy_all - expect(WebMock).to have_requested(:post, @system_hook.url).with( - body: /user_remove_from_group/ - ).once - end - - end -end diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb deleted file mode 100644 index 67ec9193ad7db5daa111c11a1fbcfca249bd1567..0000000000000000000000000000000000000000 --- a/spec/models/hooks/web_hook_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) default("ProjectHook") -# service_id :integer -# push_events :boolean default(TRUE), not null -# issues_events :boolean default(FALSE), not null -# merge_requests_events :boolean default(FALSE), not null -# tag_push_events :boolean default(FALSE) -# - -require 'spec_helper' - -describe ProjectHook do - describe "Associations" do - it { is_expected.to belong_to :project } - end - - describe "Mass assignment" do - end - - describe "Validations" do - it { is_expected.to validate_presence_of(:url) } - - context "url format" do - it { is_expected.to allow_value("http://example.com").for(:url) } - it { is_expected.to allow_value("https://excample.com").for(:url) } - it { is_expected.to allow_value("http://test.com/api").for(:url) } - it { is_expected.to allow_value("http://test.com/api?key=abc").for(:url) } - it { is_expected.to allow_value("http://test.com/api?key=abc&type=def").for(:url) } - - it { is_expected.not_to allow_value("example.com").for(:url) } - it { is_expected.not_to allow_value("ftp://example.com").for(:url) } - it { is_expected.not_to allow_value("herp-and-derp").for(:url) } - end - end - - describe "execute" do - before(:each) do - @project_hook = create(:project_hook) - @project = create(:project) - @project.hooks << [@project_hook] - @data = { before: 'oldrev', after: 'newrev', ref: 'ref'} - - WebMock.stub_request(:post, @project_hook.url) - end - - it "POSTs to the web hook URL" do - @project_hook.execute(@data) - expect(WebMock).to have_requested(:post, @project_hook.url).once - end - - it "POSTs the data as JSON" do - json = @data.to_json - - @project_hook.execute(@data) - expect(WebMock).to have_requested(:post, @project_hook.url).with(body: json).once - end - - it "catches exceptions" do - expect(WebHook).to receive(:post).and_raise("Some HTTP Post error") - - expect { - @project_hook.execute(@data) - }.to raise_error - end - end -end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb deleted file mode 100644 index 087e40c3d840e86faa9ca49049282d6d2cc1d0b3..0000000000000000000000000000000000000000 --- a/spec/models/issue_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -# == Schema Information -# -# Table name: issues -# -# id :integer not null, primary key -# title :string(255) -# assignee_id :integer -# author_id :integer -# project_id :integer -# created_at :datetime -# updated_at :datetime -# position :integer default(0) -# branch_name :string(255) -# description :text -# milestone_id :integer -# state :string(255) -# iid :integer -# - -require 'spec_helper' - -describe Issue do - describe "Associations" do - it { is_expected.to belong_to(:milestone) } - end - - describe "Mass assignment" do - end - - describe 'modules' do - it { is_expected.to include_module(Issuable) } - end - - subject { create(:issue) } - - describe '#is_being_reassigned?' do - it 'returns true if the issue assignee has changed' do - subject.assignee = create(:user) - expect(subject.is_being_reassigned?).to be_truthy - end - it 'returns false if the issue assignee has not changed' do - expect(subject.is_being_reassigned?).to be_falsey - end - end - - describe '#is_being_reassigned?' do - it 'returns issues assigned to user' do - user = create :user - - 2.times do - issue = create :issue, assignee: user - end - - expect(Issue.open_for(user).count).to eq 2 - end - end - - it_behaves_like 'an editable mentionable' do - let(:subject) { create :issue, project: mproject } - let(:backref_text) { "issue ##{subject.iid}" } - let(:set_mentionable_text) { ->(txt){ subject.description = txt } } - end - - it_behaves_like 'a Taskable' do - let(:subject) { create :issue } - end -end diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb deleted file mode 100644 index 2fb651bef1b2e15235040cc3a2ed66229a21a653..0000000000000000000000000000000000000000 --- a/spec/models/key_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime -# updated_at :datetime -# key :text -# title :string(255) -# type :string(255) -# fingerprint :string(255) -# - -require 'spec_helper' - -describe Key do - describe "Associations" do - it { is_expected.to belong_to(:user) } - end - - describe "Mass assignment" do - end - - describe "Validation" do - it { is_expected.to validate_presence_of(:title) } - it { is_expected.to validate_presence_of(:key) } - it { is_expected.to ensure_length_of(:title).is_within(0..255) } - it { is_expected.to ensure_length_of(:key).is_within(0..5000) } - end - - describe "Methods" do - it { is_expected.to respond_to :projects } - end - - context "validation of uniqueness" do - let(:user) { create(:user) } - - it "accepts the key once" do - expect(build(:key, user: user)).to be_valid - end - - it "does not accept the exact same key twice" do - create(:key, user: user) - expect(build(:key, user: user)).not_to be_valid - end - - it "does not accept a duplicate key with a different comment" do - create(:key, user: user) - duplicate = build(:key, user: user) - duplicate.key << ' extra comment' - expect(duplicate).not_to be_valid - end - end - - context "validate it is a fingerprintable key" do - it "accepts the fingerprintable key" do - expect(build(:key)).to be_valid - end - - it 'rejects an unfingerprintable key that contains a space' do - key = build(:key) - - # Not always the middle, but close enough - key.key = key.key[0..100] + ' ' + key.key[100..-1] - - expect(key).not_to be_valid - end - - it 'rejects the unfingerprintable key (not a key)' do - expect(build(:key, key: 'ssh-rsa an-invalid-key==')).not_to be_valid - end - end - - context 'callbacks' do - it 'should add new key to authorized_file' do - @key = build(:personal_key, id: 7) - expect(GitlabShellWorker).to receive(:perform_async).with(:add_key, @key.shell_id, @key.key) - @key.save - end - - it 'should remove key from authorized_file' do - @key = create(:personal_key) - expect(GitlabShellWorker).to receive(:perform_async).with(:remove_key, @key.shell_id, @key.key) - @key.destroy - end - end -end diff --git a/spec/models/label_link_spec.rb b/spec/models/label_link_spec.rb deleted file mode 100644 index 8c240826582807ad8614fc75602e4d9e7f2a0f9b..0000000000000000000000000000000000000000 --- a/spec/models/label_link_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# == Schema Information -# -# Table name: label_links -# -# id :integer not null, primary key -# label_id :integer -# target_id :integer -# target_type :string(255) -# created_at :datetime -# updated_at :datetime -# - -require 'spec_helper' - -describe LabelLink do - let(:label) { create(:label_link) } - it { expect(label).to be_valid } - - it { is_expected.to belong_to(:label) } - it { is_expected.to belong_to(:target) } -end diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb deleted file mode 100644 index 8644ac46605af0a17c6e4c43e3254a510d9f971b..0000000000000000000000000000000000000000 --- a/spec/models/label_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -# == Schema Information -# -# Table name: labels -# -# id :integer not null, primary key -# title :string(255) -# color :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# - -require 'spec_helper' - -describe Label do - let(:label) { create(:label) } - it { expect(label).to be_valid } - - it { is_expected.to belong_to(:project) } - - describe 'Validation' do - it 'should validate color code' do - expect(build(:label, color: 'G-ITLAB')).not_to be_valid - expect(build(:label, color: 'AABBCC')).not_to be_valid - expect(build(:label, color: '#AABBCCEE')).not_to be_valid - expect(build(:label, color: '#GGHHII')).not_to be_valid - expect(build(:label, color: '#')).not_to be_valid - expect(build(:label, color: '')).not_to be_valid - - expect(build(:label, color: '#AABBCC')).to be_valid - end - - it 'should validate title' do - expect(build(:label, title: 'G,ITLAB')).not_to be_valid - expect(build(:label, title: 'G?ITLAB')).not_to be_valid - expect(build(:label, title: 'G&ITLAB')).not_to be_valid - expect(build(:label, title: '')).not_to be_valid - - expect(build(:label, title: 'GITLAB')).to be_valid - expect(build(:label, title: 'gitlab')).to be_valid - end - end -end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb deleted file mode 100644 index 56d030a03b35a7bd6d1538e1ecde1b93f80518c1..0000000000000000000000000000000000000000 --- a/spec/models/member_spec.rb +++ /dev/null @@ -1,148 +0,0 @@ -require 'spec_helper' - -describe Member do - describe "Associations" do - it { is_expected.to belong_to(:user) } - end - - describe "Validation" do - subject { Member.new(access_level: Member::GUEST) } - - it { is_expected.to validate_presence_of(:user) } - it { is_expected.to validate_presence_of(:source) } - it { is_expected.to validate_inclusion_of(:access_level).in_array(Gitlab::Access.values) } - - context "when an invite email is provided" do - let(:member) { build(:project_member, invite_email: "user@example.com", user: nil) } - - it "doesn't require a user" do - expect(member).to be_valid - end - - it "requires a valid invite email" do - member.invite_email = "nope" - - expect(member).not_to be_valid - end - - it "requires a unique invite email scoped to this source" do - create(:project_member, source: member.source, invite_email: member.invite_email) - - expect(member).not_to be_valid - end - - it "is valid otherwise" do - expect(member).to be_valid - end - end - - context "when an invite email is not provided" do - let(:member) { build(:project_member) } - - it "requires a user" do - member.user = nil - - expect(member).not_to be_valid - end - - it "is valid otherwise" do - expect(member).to be_valid - end - end - end - - describe "Delegate methods" do - it { is_expected.to respond_to(:user_name) } - it { is_expected.to respond_to(:user_email) } - end - - describe ".add_user" do - let!(:user) { create(:user) } - let(:project) { create(:project) } - - context "when called with a user id" do - it "adds the user as a member" do - Member.add_user(project.project_members, user.id, ProjectMember::MASTER) - - expect(project.users).to include(user) - end - end - - context "when called with a user object" do - it "adds the user as a member" do - Member.add_user(project.project_members, user, ProjectMember::MASTER) - - expect(project.users).to include(user) - end - end - - context "when called with a known user email" do - it "adds the user as a member" do - Member.add_user(project.project_members, user.email, ProjectMember::MASTER) - - expect(project.users).to include(user) - end - end - - context "when called with an unknown user email" do - it "adds a member invite" do - Member.add_user(project.project_members, "user@example.com", ProjectMember::MASTER) - - expect(project.project_members.invite.pluck(:invite_email)).to include("user@example.com") - end - end - end - - describe "#accept_invite!" do - let!(:member) { create(:project_member, invite_email: "user@example.com", user: nil) } - let(:user) { create(:user) } - - it "resets the invite token" do - member.accept_invite!(user) - - expect(member.invite_token).to be_nil - end - - it "sets the invite accepted timestamp" do - member.accept_invite!(user) - - expect(member.invite_accepted_at).not_to be_nil - end - - it "sets the user" do - member.accept_invite!(user) - - expect(member.user).to eq(user) - end - - it "calls #after_accept_invite" do - expect(member).to receive(:after_accept_invite) - - member.accept_invite!(user) - end - end - - describe "#decline_invite!" do - let!(:member) { create(:project_member, invite_email: "user@example.com", user: nil) } - - it "destroys the member" do - member.decline_invite! - - expect(member).to be_destroyed - end - - it "calls #after_decline_invite" do - expect(member).to receive(:after_decline_invite) - - member.decline_invite! - end - end - - describe "#generate_invite_token" do - let!(:member) { create(:project_member, invite_email: "user@example.com", user: nil) } - - it "sets the invite token" do - expect { member.generate_invite_token }.to change { member.invite_token} - end - end -end diff --git a/spec/models/members/group_member_spec.rb b/spec/models/members/group_member_spec.rb deleted file mode 100644 index e206c11f33ae43bb117f1d899307cd60de1a8e08..0000000000000000000000000000000000000000 --- a/spec/models/members/group_member_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string(255) not null -# user_id :integer not null -# notification_level :integer not null -# type :string(255) -# created_at :datetime -# updated_at :datetime -# - -require 'spec_helper' - -describe GroupMember do - context 'notification' do - describe "#after_create" do - it "should send email to user" do - membership = build(:group_member) - membership.stub(notification_service: double('NotificationService').as_null_object) - expect(membership).to receive(:notification_service) - membership.save - end - end - - describe "#after_update" do - before do - @group_member = create :group_member - @group_member.stub(notification_service: double('NotificationService').as_null_object) - end - - it "should send email to user" do - expect(@group_member).to receive(:notification_service) - @group_member.update_attribute(:access_level, GroupMember::MASTER) - end - - it "does not send an email when the access level has not changed" do - expect(@group_member).not_to receive(:notification_service) - @group_member.update_attribute(:access_level, GroupMember::OWNER) - end - end - end -end diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb deleted file mode 100644 index 521721f3577ee2cba82abdc7c9b4a88fe3131ee7..0000000000000000000000000000000000000000 --- a/spec/models/members/project_member_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -# == Schema Information -# -# Table name: members -# -# id :integer not null, primary key -# access_level :integer not null -# source_id :integer not null -# source_type :string(255) not null -# user_id :integer not null -# notification_level :integer not null -# type :string(255) -# created_at :datetime -# updated_at :datetime -# - -require 'spec_helper' - -describe ProjectMember do - describe :import_team do - before do - @abilities = Six.new - @abilities << Ability - - @project_1 = create :project - @project_2 = create :project - - @user_1 = create :user - @user_2 = create :user - - @project_1.team << [ @user_1, :developer ] - @project_2.team << [ @user_2, :reporter ] - - @status = @project_2.team.import(@project_1) - end - - it { expect(@status).to be_truthy } - - describe 'project 2 should get user 1 as developer. user_2 should not be changed' do - it { expect(@project_2.users).to include(@user_1) } - it { expect(@project_2.users).to include(@user_2) } - - it { expect(@abilities.allowed?(@user_1, :write_project, @project_2)).to be_truthy } - it { expect(@abilities.allowed?(@user_2, :read_project, @project_2)).to be_truthy } - end - - describe 'project 1 should not be changed' do - it { expect(@project_1.users).to include(@user_1) } - it { expect(@project_1.users).not_to include(@user_2) } - end - end - - describe :add_users_into_projects do - before do - @project_1 = create :project - @project_2 = create :project - - @user_1 = create :user - @user_2 = create :user - - ProjectMember.add_users_into_projects( - [@project_1.id, @project_2.id], - [@user_1.id, @user_2.id], - ProjectMember::MASTER - ) - end - - it { expect(@project_1.users).to include(@user_1) } - it { expect(@project_1.users).to include(@user_2) } - - - it { expect(@project_2.users).to include(@user_1) } - it { expect(@project_2.users).to include(@user_2) } - end - - describe :truncate_teams do - before do - @project_1 = create :project - @project_2 = create :project - - @user_1 = create :user - @user_2 = create :user - - @project_1.team << [ @user_1, :developer] - @project_2.team << [ @user_2, :reporter] - - ProjectMember.truncate_teams([@project_1.id, @project_2.id]) - end - - it { expect(@project_1.users).to be_empty } - it { expect(@project_2.users).to be_empty } - end -end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb deleted file mode 100644 index d40503d791cad7a6c6f8ab9a8b4fbd18a933020b..0000000000000000000000000000000000000000 --- a/spec/models/merge_request_spec.rb +++ /dev/null @@ -1,127 +0,0 @@ -# == Schema Information -# -# Table name: merge_requests -# -# id :integer not null, primary key -# target_branch :string(255) not null -# source_branch :string(255) not null -# source_project_id :integer not null -# author_id :integer -# assignee_id :integer -# title :string(255) -# created_at :datetime -# updated_at :datetime -# milestone_id :integer -# state :string(255) -# merge_status :string(255) -# target_project_id :integer not null -# iid :integer -# description :text -# position :integer default(0) -# locked_at :datetime -# - -require 'spec_helper' - -describe MergeRequest do - describe "Validation" do - it { is_expected.to validate_presence_of(:target_branch) } - it { is_expected.to validate_presence_of(:source_branch) } - end - - describe "Mass assignment" do - end - - describe "Respond to" do - it { is_expected.to respond_to(:unchecked?) } - it { is_expected.to respond_to(:can_be_merged?) } - it { is_expected.to respond_to(:cannot_be_merged?) } - end - - describe 'modules' do - it { is_expected.to include_module(Issuable) } - end - - describe "#mr_and_commit_notes" do - let!(:merge_request) { create(:merge_request) } - - before do - allow(merge_request).to receive(:commits) { [merge_request.source_project.repository.commit] } - create(:note, commit_id: merge_request.commits.first.id, noteable_type: 'Commit', project: merge_request.project) - create(:note, noteable: merge_request, project: merge_request.project) - end - - it "should include notes for commits" do - expect(merge_request.commits).not_to be_empty - expect(merge_request.mr_and_commit_notes.count).to eq(2) - end - end - - subject { create(:merge_request) } - - describe '#is_being_reassigned?' do - it 'returns true if the merge_request assignee has changed' do - subject.assignee = create(:user) - expect(subject.is_being_reassigned?).to be_truthy - end - it 'returns false if the merge request assignee has not changed' do - expect(subject.is_being_reassigned?).to be_falsey - end - end - - describe '#for_fork?' do - it 'returns true if the merge request is for a fork' do - subject.source_project = create(:project, namespace: create(:group)) - subject.target_project = create(:project, namespace: create(:group)) - - expect(subject.for_fork?).to be_truthy - end - - it 'returns false if is not for a fork' do - expect(subject.for_fork?).to be_falsey - end - end - - describe 'detection of issues to be closed' do - let(:issue0) { create :issue, project: subject.project } - let(:issue1) { create :issue, project: subject.project } - let(:commit0) { double('commit0', closes_issues: [issue0]) } - let(:commit1) { double('commit1', closes_issues: [issue0]) } - let(:commit2) { double('commit2', closes_issues: [issue1]) } - - before do - subject.stub(commits: [commit0, commit1, commit2]) - end - - it 'accesses the set of issues that will be closed on acceptance' do - subject.project.stub(default_branch: subject.target_branch) - - expect(subject.closes_issues).to eq([issue0, issue1].sort_by(&:id)) - end - - it 'only lists issues as to be closed if it targets the default branch' do - subject.project.stub(default_branch: 'master') - subject.target_branch = 'something-else' - - expect(subject.closes_issues).to be_empty - end - - it 'detects issues mentioned in the description' do - issue2 = create(:issue, project: subject.project) - subject.description = "Closes ##{issue2.iid}" - subject.project.stub(default_branch: subject.target_branch) - - expect(subject.closes_issues).to include(issue2) - end - end - - it_behaves_like 'an editable mentionable' do - let(:subject) { create :merge_request, source_project: mproject, target_project: mproject } - let(:backref_text) { "merge request !#{subject.iid}" } - let(:set_mentionable_text) { ->(txt){ subject.title = txt } } - end - - it_behaves_like 'a Taskable' do - let(:subject) { create :merge_request, :simple } - end -end diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb deleted file mode 100644 index 45171e1bf6459a35e4b7c0a4e227cdfc2b9d69f4..0000000000000000000000000000000000000000 --- a/spec/models/milestone_spec.rb +++ /dev/null @@ -1,143 +0,0 @@ -# == Schema Information -# -# Table name: milestones -# -# id :integer not null, primary key -# title :string(255) not null -# project_id :integer not null -# description :text -# due_date :date -# created_at :datetime -# updated_at :datetime -# state :string(255) -# iid :integer -# - -require 'spec_helper' - -describe Milestone do - describe "Associations" do - it { is_expected.to belong_to(:project) } - it { is_expected.to have_many(:issues) } - end - - describe "Mass assignment" do - end - - describe "Validation" do - before { subject.stub(set_iid: false) } - it { is_expected.to validate_presence_of(:title) } - it { is_expected.to validate_presence_of(:project) } - end - - let(:milestone) { create(:milestone) } - let(:issue) { create(:issue) } - - describe "#percent_complete" do - it "should not count open issues" do - milestone.issues << issue - expect(milestone.percent_complete).to eq(0) - end - - it "should count closed issues" do - issue.close - milestone.issues << issue - expect(milestone.percent_complete).to eq(100) - end - - it "should recover from dividing by zero" do - expect(milestone.issues).to receive(:count).and_return(0) - expect(milestone.percent_complete).to eq(100) - end - end - - describe "#expires_at" do - it "should be nil when due_date is unset" do - milestone.update_attributes(due_date: nil) - expect(milestone.expires_at).to be_nil - end - - it "should not be nil when due_date is set" do - milestone.update_attributes(due_date: Date.tomorrow) - expect(milestone.expires_at).to be_present - end - end - - describe :expired? do - context "expired" do - before do - milestone.stub(due_date: Date.today.prev_year) - end - - it { expect(milestone.expired?).to be_truthy } - end - - context "not expired" do - before do - milestone.stub(due_date: Date.today.next_year) - end - - it { expect(milestone.expired?).to be_falsey } - end - end - - describe :percent_complete do - before do - milestone.stub( - closed_items_count: 3, - total_items_count: 4 - ) - end - - it { expect(milestone.percent_complete).to eq(75) } - end - - describe :items_count do - before do - milestone.issues << create(:issue) - milestone.issues << create(:closed_issue) - milestone.merge_requests << create(:merge_request) - end - - it { expect(milestone.closed_items_count).to eq(1) } - it { expect(milestone.open_items_count).to eq(2) } - it { expect(milestone.total_items_count).to eq(3) } - it { expect(milestone.is_empty?).to be_falsey } - end - - describe :can_be_closed? do - it { expect(milestone.can_be_closed?).to be_truthy } - end - - describe :is_empty? do - before do - issue = create :closed_issue, milestone: milestone - merge_request = create :merge_request, milestone: milestone - end - - it 'Should return total count of issues and merge requests assigned to milestone' do - expect(milestone.total_items_count).to eq 2 - end - end - - describe :can_be_closed? do - before do - milestone = create :milestone - create :closed_issue, milestone: milestone - - issue = create :issue - end - - it 'should be true if milestone active and all nested issues closed' do - expect(milestone.can_be_closed?).to be_truthy - end - - it 'should be false if milestone active and not all nested issues closed' do - issue.milestone = milestone - issue.save - - expect(milestone.can_be_closed?).to be_falsey - end - end - -end diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb deleted file mode 100644 index e87432fdf6263663d56cf6a7d69afc47d47eab0d..0000000000000000000000000000000000000000 --- a/spec/models/namespace_spec.rb +++ /dev/null @@ -1,96 +0,0 @@ -# == Schema Information -# -# Table name: namespaces -# -# id :integer not null, primary key -# name :string(255) not null -# path :string(255) not null -# owner_id :integer -# created_at :datetime -# updated_at :datetime -# type :string(255) -# description :string(255) default(""), not null -# avatar :string(255) -# - -require 'spec_helper' - -describe Namespace do - let!(:namespace) { create(:namespace) } - - it { is_expected.to have_many :projects } - it { is_expected.to validate_presence_of :name } - it { is_expected.to validate_uniqueness_of(:name) } - it { is_expected.to validate_presence_of :path } - it { is_expected.to validate_uniqueness_of(:path) } - it { is_expected.to validate_presence_of :owner } - - describe "Mass assignment" do - end - - describe "Respond to" do - it { is_expected.to respond_to(:human_name) } - it { is_expected.to respond_to(:to_param) } - end - - describe :to_param do - it { expect(namespace.to_param).to eq(namespace.path) } - end - - describe :human_name do - it { expect(namespace.human_name).to eq(namespace.owner_name) } - end - - describe :search do - before do - @namespace = create :namespace - end - - it { expect(Namespace.search(@namespace.path)).to eq([@namespace]) } - it { expect(Namespace.search('unknown')).to eq([]) } - end - - describe :move_dir do - before do - @namespace = create :namespace - @namespace.stub(path_changed?: true) - end - - it "should raise error when directory exists" do - expect { @namespace.move_dir }.to raise_error("namespace directory cannot be moved") - end - - it "should move dir if path changed" do - new_path = @namespace.path + "_new" - @namespace.stub(path_was: @namespace.path) - @namespace.stub(path: new_path) - expect(@namespace.move_dir).to be_truthy - end - end - - describe :rm_dir do - it "should remove dir" do - expect(namespace.rm_dir).to be_truthy - end - end - - describe :find_by_path_or_name do - before do - @namespace = create(:namespace, name: 'WoW', path: 'woW') - end - - it { expect(Namespace.find_by_path_or_name('wow')).to eq(@namespace) } - it { expect(Namespace.find_by_path_or_name('WOW')).to eq(@namespace) } - it { expect(Namespace.find_by_path_or_name('unknown')).to eq(nil) } - end - - describe ".clean_path" do - - let!(:user) { create(:user, username: "johngitlab-etc") } - let!(:namespace) { create(:namespace, path: "JohnGitLab-etc1") } - - it "cleans the path and makes sure it's available" do - expect(Namespace.clean_path("-john+gitlab-ETC%.git@gmail.com")).to eq("johngitlab-ETC2") - end - end -end diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb deleted file mode 100644 index a7bf5081d5b8a9c98176301132c712ab8e5823de..0000000000000000000000000000000000000000 --- a/spec/models/note_spec.rb +++ /dev/null @@ -1,637 +0,0 @@ -# == Schema Information -# -# Table name: notes -# -# id :integer not null, primary key -# note :text -# noteable_type :string(255) -# author_id :integer -# created_at :datetime -# updated_at :datetime -# project_id :integer -# attachment :string(255) -# line_code :string(255) -# commit_id :string(255) -# noteable_id :integer -# system :boolean default(FALSE), not null -# st_diff :text -# - -require 'spec_helper' - -describe Note do - describe "Associations" do - it { is_expected.to belong_to(:project) } - it { is_expected.to belong_to(:noteable) } - it { is_expected.to belong_to(:author).class_name('User') } - end - - describe "Mass assignment" do - end - - describe "Validation" do - it { is_expected.to validate_presence_of(:note) } - it { is_expected.to validate_presence_of(:project) } - end - - describe "Voting score" do - let(:project) { create(:project) } - - it "recognizes a neutral note" do - note = create(:votable_note, note: "This is not a +1 note") - expect(note).not_to be_upvote - expect(note).not_to be_downvote - end - - it "recognizes a neutral emoji note" do - note = build(:votable_note, note: "I would :+1: this, but I don't want to") - expect(note).not_to be_upvote - expect(note).not_to be_downvote - end - - it "recognizes a +1 note" do - note = create(:votable_note, note: "+1 for this") - expect(note).to be_upvote - end - - it "recognizes a +1 emoji as a vote" do - note = build(:votable_note, note: ":+1: for this") - expect(note).to be_upvote - end - - it "recognizes a thumbsup emoji as a vote" do - note = build(:votable_note, note: ":thumbsup: for this") - expect(note).to be_upvote - end - - it "recognizes a -1 note" do - note = create(:votable_note, note: "-1 for this") - expect(note).to be_downvote - end - - it "recognizes a -1 emoji as a vote" do - note = build(:votable_note, note: ":-1: for this") - expect(note).to be_downvote - end - - it "recognizes a thumbsdown emoji as a vote" do - note = build(:votable_note, note: ":thumbsdown: for this") - expect(note).to be_downvote - end - end - - let(:project) { create(:project) } - - describe "Commit notes" do - let!(:note) { create(:note_on_commit, note: "+1 from me") } - let!(:commit) { note.noteable } - - it "should be accessible through #noteable" do - expect(note.commit_id).to eq(commit.id) - expect(note.noteable).to be_a(Commit) - expect(note.noteable).to eq(commit) - end - - it "should save a valid note" do - expect(note.commit_id).to eq(commit.id) - note.noteable == commit - end - - it "should be recognized by #for_commit?" do - expect(note).to be_for_commit - end - - it "should not be votable" do - expect(note).not_to be_votable - end - end - - describe "Commit diff line notes" do - let!(:note) { create(:note_on_commit_diff, note: "+1 from me") } - let!(:commit) { note.noteable } - - it "should save a valid note" do - expect(note.commit_id).to eq(commit.id) - expect(note.noteable.id).to eq(commit.id) - end - - it "should be recognized by #for_diff_line?" do - expect(note).to be_for_diff_line - end - - it "should be recognized by #for_commit_diff_line?" do - expect(note).to be_for_commit_diff_line - end - - it "should not be votable" do - expect(note).not_to be_votable - end - end - - describe "Issue notes" do - let!(:note) { create(:note_on_issue, note: "+1 from me") } - - it "should not be votable" do - expect(note).to be_votable - end - end - - describe "Merge request notes" do - let!(:note) { create(:note_on_merge_request, note: "+1 from me") } - - it "should be votable" do - expect(note).to be_votable - end - end - - describe "Merge request diff line notes" do - let!(:note) { create(:note_on_merge_request_diff, note: "+1 from me") } - - it "should not be votable" do - expect(note).not_to be_votable - end - end - - describe '#create_status_change_note' do - let(:project) { create(:project) } - let(:thing) { create(:issue, project: project) } - let(:author) { create(:user) } - let(:status) { 'new_status' } - - subject { Note.create_status_change_note(thing, project, author, status, nil) } - - it 'creates and saves a Note' do - is_expected.to be_a Note - expect(subject.id).not_to be_nil - end - - describe '#noteable' do - subject { super().noteable } - it { is_expected.to eq(thing) } - end - - describe '#project' do - subject { super().project } - it { is_expected.to eq(thing.project) } - end - - describe '#author' do - subject { super().author } - it { is_expected.to eq(author) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("Status changed to #{status}") } - end - - it 'appends a back-reference if a closing mentionable is supplied' do - commit = double('commit', gfm_reference: 'commit 123456') - n = Note.create_status_change_note(thing, project, author, status, commit) - - expect(n.note).to eq("Status changed to #{status} by commit 123456") - end - end - - describe '#create_assignee_change_note' do - let(:project) { create(:project) } - let(:thing) { create(:issue, project: project) } - let(:author) { create(:user) } - let(:assignee) { create(:user, username: "assigned_user") } - - subject { Note.create_assignee_change_note(thing, project, author, assignee) } - - context 'creates and saves a Note' do - it { is_expected.to be_a Note } - - describe '#id' do - subject { super().id } - it { is_expected.not_to be_nil } - end - end - - describe '#noteable' do - subject { super().noteable } - it { is_expected.to eq(thing) } - end - - describe '#project' do - subject { super().project } - it { is_expected.to eq(thing.project) } - end - - describe '#author' do - subject { super().author } - it { is_expected.to eq(author) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq('Reassigned to @assigned_user') } - end - - context 'assignee is removed' do - let(:assignee) { nil } - - describe '#note' do - subject { super().note } - it { is_expected.to eq('Assignee removed') } - end - end - end - - describe '#create_labels_change_note' do - let(:project) { create(:project) } - let(:thing) { create(:issue, project: project) } - let(:author) { create(:user) } - let(:label1) { create(:label) } - let(:label2) { create(:label) } - let(:added_labels) { [label1, label2] } - let(:removed_labels) { [] } - - subject { Note.create_labels_change_note(thing, project, author, added_labels, removed_labels) } - - context 'creates and saves a Note' do - it { is_expected.to be_a Note } - - describe '#id' do - subject { super().id } - it { is_expected.not_to be_nil } - end - end - - describe '#noteable' do - subject { super().noteable } - it { is_expected.to eq(thing) } - end - - describe '#project' do - subject { super().project } - it { is_expected.to eq(thing.project) } - end - - describe '#author' do - subject { super().author } - it { is_expected.to eq(author) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("Added ~#{label1.id} ~#{label2.id} labels") } - end - - context 'label is removed' do - let(:added_labels) { [label1] } - let(:removed_labels) { [label2] } - - describe '#note' do - subject { super().note } - it { is_expected.to eq("Added ~#{label1.id} and removed ~#{label2.id} labels") } - end - end - end - - describe '#create_milestone_change_note' do - let(:project) { create(:project) } - let(:thing) { create(:issue, project: project) } - let(:milestone) { create(:milestone, project: project, title: "first_milestone") } - let(:author) { create(:user) } - - subject { Note.create_milestone_change_note(thing, project, author, milestone) } - - context 'creates and saves a Note' do - it { is_expected.to be_a Note } - - describe '#id' do - subject { super().id } - it { is_expected.not_to be_nil } - end - end - - describe '#project' do - subject { super().project } - it { is_expected.to eq(thing.project) } - end - - describe '#author' do - subject { super().author } - it { is_expected.to eq(author) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("Milestone changed to first_milestone") } - end - end - - describe '#create_cross_reference_note' do - let(:project) { create(:project) } - let(:author) { create(:user) } - let(:issue) { create(:issue, project: project) } - let(:mergereq) { create(:merge_request, :simple, target_project: project, source_project: project) } - let(:commit) { project.repository.commit } - - # Test all of {issue, merge request, commit} in both the referenced and referencing - # roles, to ensure that the correct information can be inferred from any argument. - - context 'issue from a merge request' do - subject { Note.create_cross_reference_note(issue, mergereq, author, project) } - - it { is_expected.to be_valid } - - describe '#noteable' do - subject { super().noteable } - it { is_expected.to eq(issue) } - end - - describe '#project' do - subject { super().project } - it { is_expected.to eq(issue.project) } - end - - describe '#author' do - subject { super().author } - it { is_expected.to eq(author) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("mentioned in merge request !#{mergereq.iid}") } - end - end - - context 'issue from a commit' do - subject { Note.create_cross_reference_note(issue, commit, author, project) } - - it { is_expected.to be_valid } - - describe '#noteable' do - subject { super().noteable } - it { is_expected.to eq(issue) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("mentioned in commit #{commit.sha}") } - end - end - - context 'merge request from an issue' do - subject { Note.create_cross_reference_note(mergereq, issue, author, project) } - - it { is_expected.to be_valid } - - describe '#noteable' do - subject { super().noteable } - it { is_expected.to eq(mergereq) } - end - - describe '#project' do - subject { super().project } - it { is_expected.to eq(mergereq.project) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("mentioned in issue ##{issue.iid}") } - end - end - - context 'commit from a merge request' do - subject { Note.create_cross_reference_note(commit, mergereq, author, project) } - - it { is_expected.to be_valid } - - describe '#noteable' do - subject { super().noteable } - it { is_expected.to eq(commit) } - end - - describe '#project' do - subject { super().project } - it { is_expected.to eq(project) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("mentioned in merge request !#{mergereq.iid}") } - end - end - - context 'commit contained in a merge request' do - subject { Note.create_cross_reference_note(mergereq.commits.first, mergereq, author, project) } - - it { is_expected.to be_nil } - end - - context 'commit from issue' do - subject { Note.create_cross_reference_note(commit, issue, author, project) } - - it { is_expected.to be_valid } - - describe '#noteable_type' do - subject { super().noteable_type } - it { is_expected.to eq("Commit") } - end - - describe '#noteable_id' do - subject { super().noteable_id } - it { is_expected.to be_nil } - end - - describe '#commit_id' do - subject { super().commit_id } - it { is_expected.to eq(commit.id) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("mentioned in issue ##{issue.iid}") } - end - end - - context 'commit from commit' do - let(:parent_commit) { commit.parents.first } - subject { Note.create_cross_reference_note(commit, parent_commit, author, project) } - - it { is_expected.to be_valid } - - describe '#noteable_type' do - subject { super().noteable_type } - it { is_expected.to eq("Commit") } - end - - describe '#noteable_id' do - subject { super().noteable_id } - it { is_expected.to be_nil } - end - - describe '#commit_id' do - subject { super().commit_id } - it { is_expected.to eq(commit.id) } - end - - describe '#note' do - subject { super().note } - it { is_expected.to eq("mentioned in commit #{parent_commit.id}") } - end - end - end - - describe '#cross_reference_exists?' do - let(:project) { create :project } - let(:author) { create :user } - let(:issue) { create :issue } - let(:commit0) { project.repository.commit } - let(:commit1) { project.repository.commit('HEAD~2') } - - before do - Note.create_cross_reference_note(issue, commit0, author, project) - end - - it 'detects if a mentionable has already been mentioned' do - expect(Note.cross_reference_exists?(issue, commit0)).to be_truthy - end - - it 'detects if a mentionable has not already been mentioned' do - expect(Note.cross_reference_exists?(issue, commit1)).to be_falsey - end - - context 'commit on commit' do - before do - Note.create_cross_reference_note(commit0, commit1, author, project) - end - - it { expect(Note.cross_reference_exists?(commit0, commit1)).to be_truthy } - it { expect(Note.cross_reference_exists?(commit1, commit0)).to be_falsey } - end - - context 'legacy note with Markdown emphasis' do - let(:issue2) { create :issue, project: project } - let!(:note) do - create :note, system: true, noteable_id: issue2.id, - noteable_type: "Issue", note: "_mentioned in issue " \ - "#{issue.project.path_with_namespace}##{issue.iid}_" - end - - it 'detects if a mentionable with emphasis has been mentioned' do - expect(Note.cross_reference_exists?(issue2, issue)).to be_truthy - end - end - end - - describe '#cross_references_with_underscores?' do - let(:project) { create :project, path: "first_project" } - let(:second_project) { create :project, path: "second_project" } - - let(:author) { create :user } - let(:issue0) { create :issue, project: project } - let(:issue1) { create :issue, project: second_project } - let!(:note) { Note.create_cross_reference_note(issue0, issue1, author, project) } - - it 'detects if a mentionable has already been mentioned' do - expect(Note.cross_reference_exists?(issue0, issue1)).to be_truthy - end - - it 'detects if a mentionable has not already been mentioned' do - expect(Note.cross_reference_exists?(issue1, issue0)).to be_falsey - end - - it 'detects that text has underscores' do - expect(note.note).to eq("mentioned in issue #{second_project.path_with_namespace}##{issue1.iid}") - end - end - - describe '#system?' do - let(:project) { create(:project) } - let(:issue) { create(:issue, project: project) } - let(:other) { create(:issue, project: project) } - let(:author) { create(:user) } - let(:assignee) { create(:user) } - let(:label) { create(:label) } - let(:milestone) { create(:milestone) } - - it 'should recognize user-supplied notes as non-system' do - @note = create(:note_on_issue) - expect(@note).not_to be_system - end - - it 'should identify status-change notes as system notes' do - @note = Note.create_status_change_note(issue, project, author, 'closed', nil) - expect(@note).to be_system - end - - it 'should identify cross-reference notes as system notes' do - @note = Note.create_cross_reference_note(issue, other, author, project) - expect(@note).to be_system - end - - it 'should identify assignee-change notes as system notes' do - @note = Note.create_assignee_change_note(issue, project, author, assignee) - expect(@note).to be_system - end - - it 'should identify label-change notes as system notes' do - @note = Note.create_labels_change_note(issue, project, author, [label], []) - expect(@note).to be_system - end - - it 'should identify milestone-change notes as system notes' do - @note = Note.create_milestone_change_note(issue, project, author, milestone) - expect(@note).to be_system - end - end - - describe :authorization do - before do - @p1 = create(:project) - @p2 = create(:project) - @u1 = create(:user) - @u2 = create(:user) - @u3 = create(:user) - @abilities = Six.new - @abilities << Ability - end - - describe :read do - before do - @p1.project_members.create(user: @u2, access_level: ProjectMember::GUEST) - @p2.project_members.create(user: @u3, access_level: ProjectMember::GUEST) - end - - it { expect(@abilities.allowed?(@u1, :read_note, @p1)).to be_falsey } - it { expect(@abilities.allowed?(@u2, :read_note, @p1)).to be_truthy } - it { expect(@abilities.allowed?(@u3, :read_note, @p1)).to be_falsey } - end - - describe :write do - before do - @p1.project_members.create(user: @u2, access_level: ProjectMember::DEVELOPER) - @p2.project_members.create(user: @u3, access_level: ProjectMember::DEVELOPER) - end - - it { expect(@abilities.allowed?(@u1, :write_note, @p1)).to be_falsey } - it { expect(@abilities.allowed?(@u2, :write_note, @p1)).to be_truthy } - it { expect(@abilities.allowed?(@u3, :write_note, @p1)).to be_falsey } - end - - describe :admin do - before do - @p1.project_members.create(user: @u1, access_level: ProjectMember::REPORTER) - @p1.project_members.create(user: @u2, access_level: ProjectMember::MASTER) - @p2.project_members.create(user: @u3, access_level: ProjectMember::MASTER) - end - - it { expect(@abilities.allowed?(@u1, :admin_note, @p1)).to be_falsey } - it { expect(@abilities.allowed?(@u2, :admin_note, @p1)).to be_truthy } - it { expect(@abilities.allowed?(@u3, :admin_note, @p1)).to be_falsey } - end - end - - it_behaves_like 'an editable mentionable' do - let(:issue) { create :issue, project: project } - let(:subject) { create :note, noteable: issue, project: project } - let(:backref_text) { issue.gfm_reference } - let(:set_mentionable_text) { ->(txt) { subject.note = txt } } - end -end diff --git a/spec/models/project_security_spec.rb b/spec/models/project_security_spec.rb deleted file mode 100644 index 1ee1900354378f7f4141a257043946ce4e02305a..0000000000000000000000000000000000000000 --- a/spec/models/project_security_spec.rb +++ /dev/null @@ -1,126 +0,0 @@ -require 'spec_helper' - -describe Project do - describe :authorization do - before do - @p1 = create(:project) - - @u1 = create(:user) - @u2 = create(:user) - @u3 = create(:user) - @u4 = @p1.owner - - @abilities = Six.new - @abilities << Ability - end - - let(:guest_actions) { Ability.project_guest_rules } - let(:report_actions) { Ability.project_report_rules } - let(:dev_actions) { Ability.project_dev_rules } - let(:master_actions) { Ability.project_master_rules } - let(:admin_actions) { Ability.project_admin_rules } - - describe "Non member rules" do - it "should deny for non-project users any actions" do - admin_actions.each do |action| - expect(@abilities.allowed?(@u1, action, @p1)).to be_falsey - end - end - end - - describe "Guest Rules" do - before do - @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::GUEST) - end - - it "should allow for project user any guest actions" do - guest_actions.each do |action| - expect(@abilities.allowed?(@u2, action, @p1)).to be_truthy - end - end - end - - describe "Report Rules" do - before do - @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::REPORTER) - end - - it "should allow for project user any report actions" do - report_actions.each do |action| - expect(@abilities.allowed?(@u2, action, @p1)).to be_truthy - end - end - end - - describe "Developer Rules" do - before do - @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::REPORTER) - @p1.project_members.create(project: @p1, user: @u3, access_level: ProjectMember::DEVELOPER) - end - - it "should deny for developer master-specific actions" do - [dev_actions - report_actions].each do |action| - expect(@abilities.allowed?(@u2, action, @p1)).to be_falsey - end - end - - it "should allow for project user any dev actions" do - dev_actions.each do |action| - expect(@abilities.allowed?(@u3, action, @p1)).to be_truthy - end - end - end - - describe "Master Rules" do - before do - @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::DEVELOPER) - @p1.project_members.create(project: @p1, user: @u3, access_level: ProjectMember::MASTER) - end - - it "should deny for developer master-specific actions" do - [master_actions - dev_actions].each do |action| - expect(@abilities.allowed?(@u2, action, @p1)).to be_falsey - end - end - - it "should allow for project user any master actions" do - master_actions.each do |action| - expect(@abilities.allowed?(@u3, action, @p1)).to be_truthy - end - end - end - - describe "Admin Rules" do - before do - @p1.project_members.create(project: @p1, user: @u2, access_level: ProjectMember::DEVELOPER) - @p1.project_members.create(project: @p1, user: @u3, access_level: ProjectMember::MASTER) - end - - it "should deny for masters admin-specific actions" do - [admin_actions - master_actions].each do |action| - expect(@abilities.allowed?(@u2, action, @p1)).to be_falsey - end - end - - it "should allow for project owner any admin actions" do - admin_actions.each do |action| - expect(@abilities.allowed?(@u4, action, @p1)).to be_truthy - end - end - end - end -end -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) -# path :string(255) -# description :text -# created_at :datetime -# updated_at :datetime -# private_flag :boolean default(TRUE), not null -# code :string(255) -# - diff --git a/spec/models/project_services/asana_service_spec.rb b/spec/models/project_services/asana_service_spec.rb deleted file mode 100644 index 13c8d54a2af522664582b7ce487b50a9a84e5235..0000000000000000000000000000000000000000 --- a/spec/models/project_services/asana_service_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe AsanaService, models: true do - describe 'Associations' do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe 'Validations' do - context 'active' do - before do - subject.active = true - end - - it { is_expected.to validate_presence_of :api_key } - end - end - - describe 'Execute' do - let(:user) { create(:user) } - let(:project) { create(:project) } - - before do - @asana = AsanaService.new - @asana.stub( - project: project, - project_id: project.id, - service_hook: true, - api_key: 'verySecret', - restrict_to_branch: 'master' - ) - end - - it 'should call Asana service to created a story' do - expect(Asana::Task).to receive(:find).with('123456').once - - @asana.check_commit('related to #123456', 'pushed') - end - - it 'should call Asana service to created a story and close a task' do - expect(Asana::Task).to receive(:find).with('456789').twice - - @asana.check_commit('fix #456789', 'pushed') - end - end -end diff --git a/spec/models/project_services/assembla_service_spec.rb b/spec/models/project_services/assembla_service_spec.rb deleted file mode 100644 index 91730da1eecdbdf7d6ec85e8dca5d8a14eb649b9..0000000000000000000000000000000000000000 --- a/spec/models/project_services/assembla_service_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe AssemblaService, models: true do - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Execute" do - let(:user) { create(:user) } - let(:project) { create(:project) } - - before do - @assembla_service = AssemblaService.new - @assembla_service.stub( - project_id: project.id, - project: project, - service_hook: true, - token: 'verySecret', - subdomain: 'project_name' - ) - @sample_data = Gitlab::PushDataBuilder.build_sample(project, user) - @api_url = 'https://atlas.assembla.com/spaces/project_name/github_tool?secret_key=verySecret' - WebMock.stub_request(:post, @api_url) - end - - it "should call Assembla API" do - @assembla_service.execute(@sample_data) - expect(WebMock).to have_requested(:post, @api_url).with( - body: /#{@sample_data[:before]}.*#{@sample_data[:after]}.*#{project.path}/ - ).once - end - end -end diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb deleted file mode 100644 index e987241f3cabadf3c2f7aeb6975159a0a5ed3a0b..0000000000000000000000000000000000000000 --- a/spec/models/project_services/buildkite_service_spec.rb +++ /dev/null @@ -1,82 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe BuildkiteService do - describe 'Associations' do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe 'commits methods' do - before do - @project = Project.new - @project.stub( - default_branch: 'default-brancho' - ) - - @service = BuildkiteService.new - @service.stub( - project: @project, - service_hook: true, - project_url: 'https://buildkite.com/account-name/example-project', - token: 'secret-sauce-webhook-token:secret-sauce-status-token' - ) - end - - describe :webhook_url do - it 'returns the webhook url' do - expect(@service.webhook_url).to eq( - 'https://webhook.buildkite.com/deliver/secret-sauce-webhook-token' - ) - end - end - - describe :commit_status_path do - it 'returns the correct status page' do - expect(@service.commit_status_path('2ab7834c')).to eq( - 'https://gitlab.buildkite.com/status/secret-sauce-status-token.json?commit=2ab7834c' - ) - end - end - - describe :build_page do - it 'returns the correct build page' do - expect(@service.build_page('2ab7834c', nil)).to eq( - 'https://buildkite.com/account-name/example-project/builds?commit=2ab7834c' - ) - end - end - - describe :builds_page do - it 'returns the correct path to the builds page' do - expect(@service.builds_path).to eq( - 'https://buildkite.com/account-name/example-project/builds?branch=default-brancho' - ) - end - end - - describe :status_img_path do - it 'returns the correct path to the status image' do - expect(@service.status_img_path).to eq('https://badge.buildkite.com/secret-sauce-status-token.svg') - end - end - end -end diff --git a/spec/models/project_services/flowdock_service_spec.rb b/spec/models/project_services/flowdock_service_spec.rb deleted file mode 100644 index 73f68301a34e309a8ff7b76b587875964c6005bb..0000000000000000000000000000000000000000 --- a/spec/models/project_services/flowdock_service_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe FlowdockService do - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Execute" do - let(:user) { create(:user) } - let(:project) { create(:project) } - - before do - @flowdock_service = FlowdockService.new - @flowdock_service.stub( - project_id: project.id, - project: project, - service_hook: true, - token: 'verySecret' - ) - @sample_data = Gitlab::PushDataBuilder.build_sample(project, user) - @api_url = 'https://api.flowdock.com/v1/git/verySecret' - WebMock.stub_request(:post, @api_url) - end - - it "should call FlowDock API" do - @flowdock_service.execute(@sample_data) - expect(WebMock).to have_requested(:post, @api_url).with( - body: /#{@sample_data[:before]}.*#{@sample_data[:after]}.*#{project.path}/ - ).once - end - end -end diff --git a/spec/models/project_services/gemnasium_service_spec.rb b/spec/models/project_services/gemnasium_service_spec.rb deleted file mode 100644 index d44064bbe6a14f839eb857b9fe9f495b3a3d788c..0000000000000000000000000000000000000000 --- a/spec/models/project_services/gemnasium_service_spec.rb +++ /dev/null @@ -1,48 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe GemnasiumService do - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Execute" do - let(:user) { create(:user) } - let(:project) { create(:project) } - - before do - @gemnasium_service = GemnasiumService.new - @gemnasium_service.stub( - project_id: project.id, - project: project, - service_hook: true, - token: 'verySecret', - api_key: 'GemnasiumUserApiKey' - ) - @sample_data = Gitlab::PushDataBuilder.build_sample(project, user) - end - it "should call Gemnasium service" do - expect(Gemnasium::GitlabService).to receive(:execute).with(an_instance_of(Hash)).once - @gemnasium_service.execute(@sample_data) - end - end -end diff --git a/spec/models/project_services/gitlab_ci_service_spec.rb b/spec/models/project_services/gitlab_ci_service_spec.rb deleted file mode 100644 index 6a557d839caaeef9575c9d4ba19dced6591befbf..0000000000000000000000000000000000000000 --- a/spec/models/project_services/gitlab_ci_service_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe GitlabCiService do - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Mass assignment" do - end - - describe 'commits methods' do - before do - @service = GitlabCiService.new - @service.stub( - service_hook: true, - project_url: 'http://ci.gitlab.org/projects/2', - token: 'verySecret' - ) - end - - describe :commit_status_path do - it { expect(@service.commit_status_path("2ab7834c", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/2ab7834c/status.json?token=verySecret")} - end - - describe :build_page do - it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/2ab7834c")} - end - end - - describe "Fork registration" do - before do - @old_project = create(:empty_project) - @project = create(:empty_project) - @user = create(:user) - - @service = GitlabCiService.new - @service.stub( - service_hook: true, - project_url: 'http://ci.gitlab.org/projects/2', - token: 'verySecret', - project: @old_project - ) - end - - it "performs http reuquest to ci" do - stub_request(:post, "http://ci.gitlab.org/api/v1/forks") - @service.fork_registration(@project, @user.private_token) - end - end -end diff --git a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb deleted file mode 100644 index f94bef5c3659f4f7e2914af185032c211b58bdf0..0000000000000000000000000000000000000000 --- a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe GitlabIssueTrackerService do - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - - describe 'project and issue urls' do - let(:project) { create(:project) } - - context 'with absolute urls' do - before do - GitlabIssueTrackerService.default_url_options[:script_name] = "/gitlab/root" - @service = project.create_gitlab_issue_tracker_service(active: true) - end - - after do - @service.destroy! - end - - it 'should give the correct path' do - expect(@service.project_url).to eq("http://localhost/gitlab/root/#{project.path_with_namespace}/issues") - expect(@service.new_issue_url).to eq("http://localhost/gitlab/root/#{project.path_with_namespace}/issues/new") - expect(@service.issue_url(432)).to eq("http://localhost/gitlab/root/#{project.path_with_namespace}/issues/432") - end - end - - context 'with relative urls' do - before do - GitlabIssueTrackerService.default_url_options[:script_name] = "/gitlab/root" - @service = project.create_gitlab_issue_tracker_service(active: true) - end - - after do - @service.destroy! - end - - it 'should give the correct path' do - expect(@service.project_path).to eq("/gitlab/root/#{project.path_with_namespace}/issues") - expect(@service.new_issue_path).to eq("/gitlab/root/#{project.path_with_namespace}/issues/new") - expect(@service.issue_path(432)).to eq("/gitlab/root/#{project.path_with_namespace}/issues/432") - end - end - end -end diff --git a/spec/models/project_services/hipchat_service_spec.rb b/spec/models/project_services/hipchat_service_spec.rb deleted file mode 100644 index 8ab847e64323f06c127ba3ecf8949590d86caff4..0000000000000000000000000000000000000000 --- a/spec/models/project_services/hipchat_service_spec.rb +++ /dev/null @@ -1,217 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe HipchatService do - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Execute" do - let(:hipchat) { HipchatService.new } - let(:user) { create(:user, username: 'username') } - let(:project) { create(:project, name: 'project') } - let(:api_url) { 'https://hipchat.example.com/v2/room/123456/notification?auth_token=verySecret' } - let(:project_name) { project.name_with_namespace.gsub(/\s/, '') } - - before(:each) do - hipchat.stub( - project_id: project.id, - project: project, - room: 123456, - server: 'https://hipchat.example.com', - token: 'verySecret' - ) - WebMock.stub_request(:post, api_url) - end - - context 'push events' do - let(:push_sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) } - - it "should call Hipchat API for push events" do - hipchat.execute(push_sample_data) - - expect(WebMock).to have_requested(:post, api_url).once - end - - it "should create a push message" do - message = hipchat.send(:create_push_message, push_sample_data) - - obj_attr = push_sample_data[:object_attributes] - branch = push_sample_data[:ref].gsub('refs/heads/', '') - expect(message).to include("#{user.name} pushed to branch " \ - "#{branch} of " \ - "#{project_name}") - end - end - - context 'tag_push events' do - let(:push_sample_data) { Gitlab::PushDataBuilder.build(project, user, Gitlab::Git::BLANK_SHA, '1' * 40, 'refs/tags/test', []) } - - it "should call Hipchat API for tag push events" do - hipchat.execute(push_sample_data) - - expect(WebMock).to have_requested(:post, api_url).once - end - - it "should create a tag push message" do - message = hipchat.send(:create_push_message, push_sample_data) - - obj_attr = push_sample_data[:object_attributes] - expect(message).to eq("#{user.name} pushed new tag " \ - "test to " \ - "#{project_name}\n") - end - end - - context 'issue events' do - let(:issue) { create(:issue, title: 'Awesome issue', description: 'please fix') } - let(:issue_service) { Issues::CreateService.new(project, user) } - let(:issues_sample_data) { issue_service.hook_data(issue, 'open') } - - it "should call Hipchat API for issue events" do - hipchat.execute(issues_sample_data) - - expect(WebMock).to have_requested(:post, api_url).once - end - - it "should create an issue message" do - message = hipchat.send(:create_issue_message, issues_sample_data) - - obj_attr = issues_sample_data[:object_attributes] - expect(message).to eq("#{user.name} opened " \ - "issue ##{obj_attr["iid"]} in " \ - "#{project_name}: " \ - "Awesome issue" \ - "
    please fix
    ") - end - end - - context 'merge request events' do - let(:merge_request) { create(:merge_request, description: 'please fix', title: 'Awesome merge request', target_project: project, source_project: project) } - let(:merge_service) { MergeRequests::CreateService.new(project, user) } - let(:merge_sample_data) { merge_service.hook_data(merge_request, 'open') } - - it "should call Hipchat API for merge requests events" do - hipchat.execute(merge_sample_data) - - expect(WebMock).to have_requested(:post, api_url).once - end - - it "should create a merge request message" do - message = hipchat.send(:create_merge_request_message, - merge_sample_data) - - obj_attr = merge_sample_data[:object_attributes] - expect(message).to eq("#{user.name} opened " \ - "merge request ##{obj_attr["iid"]} in " \ - "#{project_name}: " \ - "Awesome merge request" \ - "
    please fix
    ") - end - end - - context "Note events" do - let(:user) { create(:user) } - let(:project) { create(:project, creator_id: user.id) } - let(:issue) { create(:issue, project: project) } - let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let(:snippet) { create(:project_snippet, project: project) } - let(:commit_note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') } - let(:merge_request_note) { create(:note_on_merge_request, noteable_id: merge_request.id, note: "merge request note") } - let(:issue_note) { create(:note_on_issue, noteable_id: issue.id, note: "issue note")} - let(:snippet_note) { create(:note_on_project_snippet, noteable_id: snippet.id, note: "snippet note") } - - it "should call Hipchat API for commit comment events" do - data = Gitlab::NoteDataBuilder.build(commit_note, user) - hipchat.execute(data) - - expect(WebMock).to have_requested(:post, api_url).once - - message = hipchat.send(:create_message, data) - - obj_attr = data[:object_attributes] - commit_id = Commit.truncate_sha(data[:commit][:id]) - title = hipchat.send(:format_title, data[:commit][:message]) - - expect(message).to eq("#{user.name} commented on " \ - "commit #{commit_id} in " \ - "#{project_name}: " \ - "#{title}" \ - "
    a comment on a commit
    ") - end - - it "should call Hipchat API for merge request comment events" do - data = Gitlab::NoteDataBuilder.build(merge_request_note, user) - hipchat.execute(data) - - expect(WebMock).to have_requested(:post, api_url).once - - message = hipchat.send(:create_message, data) - - obj_attr = data[:object_attributes] - merge_id = data[:merge_request]['iid'] - title = data[:merge_request]['title'] - - expect(message).to eq("#{user.name} commented on " \ - "merge request ##{merge_id} in " \ - "#{project_name}: " \ - "#{title}" \ - "
    merge request note
    ") - end - - it "should call Hipchat API for issue comment events" do - data = Gitlab::NoteDataBuilder.build(issue_note, user) - hipchat.execute(data) - - message = hipchat.send(:create_message, data) - - obj_attr = data[:object_attributes] - issue_id = data[:issue]['iid'] - title = data[:issue]['title'] - - expect(message).to eq("#{user.name} commented on " \ - "issue ##{issue_id} in " \ - "#{project_name}: " \ - "#{title}" \ - "
    issue note
    ") - end - - it "should call Hipchat API for snippet comment events" do - data = Gitlab::NoteDataBuilder.build(snippet_note, user) - hipchat.execute(data) - - expect(WebMock).to have_requested(:post, api_url).once - - message = hipchat.send(:create_message, data) - - obj_attr = data[:object_attributes] - snippet_id = data[:snippet]['id'] - title = data[:snippet]['title'] - - expect(message).to eq("#{user.name} commented on " \ - "snippet ##{snippet_id} in " \ - "#{project_name}: " \ - "#{title}" \ - "
    snippet note
    ") - end - end - end -end diff --git a/spec/models/project_services/irker_service_spec.rb b/spec/models/project_services/irker_service_spec.rb deleted file mode 100644 index d55399bc360102ea6037502ce6adba53013dea4e..0000000000000000000000000000000000000000 --- a/spec/models/project_services/irker_service_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' -require 'socket' -require 'json' - -describe IrkerService do - describe 'Associations' do - it { should belong_to :project } - it { should have_one :service_hook } - end - - describe 'Validations' do - before do - subject.active = true - subject.properties['recipients'] = _recipients - end - - context 'active' do - let(:_recipients) { nil } - it { should validate_presence_of :recipients } - end - - context 'too many recipients' do - let(:_recipients) { 'a b c d' } - it 'should add an error if there is too many recipients' do - subject.send :check_recipients_count - subject.errors.should_not be_blank - end - end - - context '3 recipients' do - let(:_recipients) { 'a b c' } - it 'should not add an error if there is 3 recipients' do - subject.send :check_recipients_count - subject.errors.should be_blank - end - end - end - - describe 'Execute' do - let(:irker) { IrkerService.new } - let(:user) { create(:user) } - let(:project) { create(:project) } - let(:sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) } - - let(:recipients) { '#commits' } - let(:colorize_messages) { '1' } - - before do - irker.stub( - active: true, - project: project, - project_id: project.id, - service_hook: true, - properties: { - 'recipients' => recipients, - 'colorize_messages' => colorize_messages - } - ) - irker.settings = { - server_ip: 'localhost', - server_port: 6659, - max_channels: 3, - default_irc_uri: 'irc://chat.freenode.net/' - } - irker.valid? - @irker_server = TCPServer.new 'localhost', 6659 - end - - after do - @irker_server.close - end - - it 'should send valid JSON messages to an Irker listener' do - irker.execute(sample_data) - - conn = @irker_server.accept - conn.readlines.each do |line| - msg = JSON.load(line.chomp("\n")) - msg.keys.should match_array(['to', 'privmsg']) - if msg['to'].is_a?(String) - msg['to'].should == 'irc://chat.freenode.net/#commits' - else - msg['to'].should match_array(['irc://chat.freenode.net/#commits']) - end - end - conn.close - end - end -end diff --git a/spec/models/project_services/jira_service_spec.rb b/spec/models/project_services/jira_service_spec.rb deleted file mode 100644 index 355911e637771a8227faac071953896ec239e5a5..0000000000000000000000000000000000000000 --- a/spec/models/project_services/jira_service_spec.rb +++ /dev/null @@ -1,102 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe JiraService do - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Validations" do - context "active" do - before do - subject.active = true - end - - it { is_expected.to validate_presence_of :project_url } - it { is_expected.to validate_presence_of :issues_url } - it { is_expected.to validate_presence_of :new_issue_url } - end - end - - describe 'description and title' do - let(:project) { create(:project) } - - context 'when it is not set' do - before do - @service = project.create_jira_service(active: true) - end - - after do - @service.destroy! - end - - it 'should be initialized' do - expect(@service.title).to eq('JIRA') - expect(@service.description).to eq("Jira issue tracker") - end - end - - context 'when it is set' do - before do - properties = { 'title' => 'Jira One', 'description' => 'Jira One issue tracker' } - @service = project.create_jira_service(active: true, properties: properties) - end - - after do - @service.destroy! - end - - it "should be correct" do - expect(@service.title).to eq('Jira One') - expect(@service.description).to eq('Jira One issue tracker') - end - end - end - - describe 'project and issue urls' do - let(:project) { create(:project) } - - context 'when gitlab.yml was initialized' do - before do - settings = { "jira" => { - "title" => "Jira", - "project_url" => "http://jira.sample/projects/project_a", - "issues_url" => "http://jira.sample/issues/:id", - "new_issue_url" => "http://jira.sample/projects/project_a/issues/new" - } - } - allow(Gitlab.config).to receive(:issues_tracker).and_return(settings) - @service = project.create_jira_service(active: true) - end - - after do - @service.destroy! - end - - it 'should be prepopulated with the settings' do - expect(@service.properties[:project_url]).to eq('http://jira.sample/projects/project_a') - expect(@service.properties[:issues_url]).to eq("http://jira.sample/issues/:id") - expect(@service.properties[:new_issue_url]).to eq("http://jira.sample/projects/project_a/issues/new") - end - end - end -end diff --git a/spec/models/project_services/pushover_service_spec.rb b/spec/models/project_services/pushover_service_spec.rb deleted file mode 100644 index 5a18fd09bfc95caf51c590106bb2ee9effbe647c..0000000000000000000000000000000000000000 --- a/spec/models/project_services/pushover_service_spec.rb +++ /dev/null @@ -1,74 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe PushoverService do - describe 'Associations' do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe 'Validations' do - context 'active' do - before do - subject.active = true - end - - it { is_expected.to validate_presence_of :api_key } - it { is_expected.to validate_presence_of :user_key } - it { is_expected.to validate_presence_of :priority } - end - end - - describe 'Execute' do - let(:pushover) { PushoverService.new } - let(:user) { create(:user) } - let(:project) { create(:project) } - let(:sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) } - - let(:api_key) { 'verySecret' } - let(:user_key) { 'verySecret' } - let(:device) { 'myDevice' } - let(:priority) { 0 } - let(:sound) { 'bike' } - let(:api_url) { 'https://api.pushover.net/1/messages.json' } - - before do - pushover.stub( - project: project, - project_id: project.id, - service_hook: true, - api_key: api_key, - user_key: user_key, - device: device, - priority: priority, - sound: sound - ) - - WebMock.stub_request(:post, api_url) - end - - it 'should call Pushover API' do - pushover.execute(sample_data) - - expect(WebMock).to have_requested(:post, api_url).once - end - end -end diff --git a/spec/models/project_services/slack_service/issue_message_spec.rb b/spec/models/project_services/slack_service/issue_message_spec.rb deleted file mode 100644 index 8bca1fef44c50f1c281ad2c405fee18e8db6b2cb..0000000000000000000000000000000000000000 --- a/spec/models/project_services/slack_service/issue_message_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'spec_helper' - -describe SlackService::IssueMessage do - subject { SlackService::IssueMessage.new(args) } - - let(:args) { - { - user: { - name: 'Test User', - username: 'Test User' - }, - project_name: 'project_name', - project_url: 'somewhere.com', - - object_attributes: { - title: 'Issue title', - id: 10, - iid: 100, - assignee_id: 1, - url: 'url', - action: 'open', - state: 'opened', - description: 'issue description' - } - } - } - - let(:color) { '#345' } - - context 'open' do - it 'returns a message regarding opening of issues' do - expect(subject.pretext).to eq( - 'Test User opened in : '\ - '*Issue title*') - expect(subject.attachments).to eq([ - { - text: "issue description", - color: color, - } - ]) - end - end - - context 'close' do - before do - args[:object_attributes][:action] = 'close' - args[:object_attributes][:state] = 'closed' - end - it 'returns a message regarding closing of issues' do - expect(subject.pretext). to eq( - 'Test User closed in : '\ - '*Issue title*') - expect(subject.attachments).to be_empty - end - end -end diff --git a/spec/models/project_services/slack_service/merge_message_spec.rb b/spec/models/project_services/slack_service/merge_message_spec.rb deleted file mode 100644 index aeb408aa766d4b164f7a6daaad07c83f25f5664e..0000000000000000000000000000000000000000 --- a/spec/models/project_services/slack_service/merge_message_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'spec_helper' - -describe SlackService::MergeMessage do - subject { SlackService::MergeMessage.new(args) } - - let(:args) { - { - user: { - name: 'Test User', - username: 'Test User' - }, - project_name: 'project_name', - project_url: 'somewhere.com', - - object_attributes: { - title: "Issue title\nSecond line", - id: 10, - iid: 100, - assignee_id: 1, - url: 'url', - state: 'opened', - description: 'issue description', - source_branch: 'source_branch', - target_branch: 'target_branch', - } - } - } - - let(:color) { '#345' } - - context 'open' do - it 'returns a message regarding opening of merge requests' do - expect(subject.pretext).to eq( - 'Test User opened '\ - 'in : *Issue title*') - expect(subject.attachments).to be_empty - end - end - - context 'close' do - before do - args[:object_attributes][:state] = 'closed' - end - it 'returns a message regarding closing of merge requests' do - expect(subject.pretext).to eq( - 'Test User closed '\ - 'in : *Issue title*') - expect(subject.attachments).to be_empty - end - end -end diff --git a/spec/models/project_services/slack_service/note_message_spec.rb b/spec/models/project_services/slack_service/note_message_spec.rb deleted file mode 100644 index 21fb575480b8fd091bf0a55ac97b4cc91895acfd..0000000000000000000000000000000000000000 --- a/spec/models/project_services/slack_service/note_message_spec.rb +++ /dev/null @@ -1,129 +0,0 @@ -require 'spec_helper' - -describe SlackService::NoteMessage do - let(:color) { '#345' } - - before do - @args = { - user: { - name: 'Test User', - username: 'username', - avatar_url: 'http://fakeavatar' - }, - project_name: 'project_name', - project_url: 'somewhere.com', - repository: { - name: 'project_name', - url: 'somewhere.com', - }, - object_attributes: { - id: 10, - note: 'comment on a commit', - url: 'url', - noteable_type: 'Commit' - } - } - end - - context 'commit notes' do - before do - @args[:object_attributes][:note] = 'comment on a commit' - @args[:object_attributes][:noteable_type] = 'Commit' - @args[:commit] = { - id: '5f163b2b95e6f53cbd428f5f0b103702a52b9a23', - message: "Added a commit message\ndetails\n123\n" - } - end - - it 'returns a message regarding notes on commits' do - message = SlackService::NoteMessage.new(@args) - expect(message.pretext).to eq("Test User commented on " \ - " in : " \ - "*Added a commit message*") - expected_attachments = [ - { - text: "comment on a commit", - color: color, - } - ] - expect(message.attachments).to eq(expected_attachments) - end - end - - context 'merge request notes' do - before do - @args[:object_attributes][:note] = 'comment on a merge request' - @args[:object_attributes][:noteable_type] = 'MergeRequest' - @args[:merge_request] = { - id: 1, - iid: 30, - title: "merge request title\ndetails\n" - } - end - it 'returns a message regarding notes on a merge request' do - message = SlackService::NoteMessage.new(@args) - expect(message.pretext).to eq("Test User commented on " \ - " in : " \ - "*merge request title*") - expected_attachments = [ - { - text: "comment on a merge request", - color: color, - } - ] - expect(message.attachments).to eq(expected_attachments) - end - end - - context 'issue notes' do - before do - @args[:object_attributes][:note] = 'comment on an issue' - @args[:object_attributes][:noteable_type] = 'Issue' - @args[:issue] = { - id: 1, - iid: 20, - title: "issue title\ndetails\n" - } - end - - it 'returns a message regarding notes on an issue' do - message = SlackService::NoteMessage.new(@args) - expect(message.pretext).to eq( - "Test User commented on " \ - " in : " \ - "*issue title*") - expected_attachments = [ - { - text: "comment on an issue", - color: color, - } - ] - expect(message.attachments).to eq(expected_attachments) - end - end - - context 'project snippet notes' do - before do - @args[:object_attributes][:note] = 'comment on a snippet' - @args[:object_attributes][:noteable_type] = 'Snippet' - @args[:snippet] = { - id: 5, - title: "snippet title\ndetails\n" - } - end - - it 'returns a message regarding notes on a project snippet' do - message = SlackService::NoteMessage.new(@args) - expect(message.pretext).to eq("Test User commented on " \ - " in : " \ - "*snippet title*") - expected_attachments = [ - { - text: "comment on a snippet", - color: color, - } - ] - expect(message.attachments).to eq(expected_attachments) - end - end -end diff --git a/spec/models/project_services/slack_service/push_message_spec.rb b/spec/models/project_services/slack_service/push_message_spec.rb deleted file mode 100644 index 10963481a1248dfee077ece3c86a6b4edb39f665..0000000000000000000000000000000000000000 --- a/spec/models/project_services/slack_service/push_message_spec.rb +++ /dev/null @@ -1,88 +0,0 @@ -require 'spec_helper' - -describe SlackService::PushMessage do - subject { SlackService::PushMessage.new(args) } - - let(:args) { - { - after: 'after', - before: 'before', - project_name: 'project_name', - ref: 'refs/heads/master', - user_name: 'user_name', - project_url: 'url' - } - } - - let(:color) { '#345' } - - context 'push' do - before do - args[:commits] = [ - { message: 'message1', url: 'url1', id: 'abcdefghijkl', author: { name: 'author1' } }, - { message: 'message2', url: 'url2', id: '123456789012', author: { name: 'author2' } }, - ] - end - - it 'returns a message regarding pushes' do - expect(subject.pretext).to eq( - 'user_name pushed to branch of '\ - ' ()' - ) - expect(subject.attachments).to eq([ - { - text: ": message1 - author1\n"\ - ": message2 - author2", - color: color, - } - ]) - end - end - - context 'tag push' do - let(:args) { - { - after: 'after', - before: Gitlab::Git::BLANK_SHA, - project_name: 'project_name', - ref: 'refs/tags/new_tag', - user_name: 'user_name', - project_url: 'url' - } - } - - it 'returns a message regarding pushes' do - expect(subject.pretext).to eq('user_name pushed new tag ' \ - ' to ' \ - '') - expect(subject.attachments).to be_empty - end - end - - context 'new branch' do - before do - args[:before] = Gitlab::Git::BLANK_SHA - end - - it 'returns a message regarding a new branch' do - expect(subject.pretext).to eq( - 'user_name pushed new branch to '\ - '' - ) - expect(subject.attachments).to be_empty - end - end - - context 'removed branch' do - before do - args[:after] = Gitlab::Git::BLANK_SHA - end - - it 'returns a message regarding a removed branch' do - expect(subject.pretext).to eq( - 'user_name removed branch master from ' - ) - expect(subject.attachments).to be_empty - end - end -end diff --git a/spec/models/project_services/slack_service_spec.rb b/spec/models/project_services/slack_service_spec.rb deleted file mode 100644 index c36506644b30c74508a91abaf5e44357a7d9ad7c..0000000000000000000000000000000000000000 --- a/spec/models/project_services/slack_service_spec.rb +++ /dev/null @@ -1,170 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe SlackService do - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Validations" do - context "active" do - before do - subject.active = true - end - - it { is_expected.to validate_presence_of :webhook } - end - end - - describe "Execute" do - let(:slack) { SlackService.new } - let(:user) { create(:user) } - let(:project) { create(:project) } - let(:push_sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) } - let(:webhook_url) { 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' } - let(:username) { 'slack_username' } - let(:channel) { 'slack_channel' } - - before do - slack.stub( - project: project, - project_id: project.id, - service_hook: true, - webhook: webhook_url - ) - - WebMock.stub_request(:post, webhook_url) - - opts = { - title: 'Awesome issue', - description: 'please fix' - } - - issue_service = Issues::CreateService.new(project, user, opts) - @issue = issue_service.execute - @issues_sample_data = issue_service.hook_data(@issue, 'open') - - opts = { - title: 'Awesome merge_request', - description: 'please fix', - source_branch: 'stable', - target_branch: 'master' - } - merge_service = MergeRequests::CreateService.new(project, - user, opts) - @merge_request = merge_service.execute - @merge_sample_data = merge_service.hook_data(@merge_request, - 'open') - end - - it "should call Slack API for push events" do - slack.execute(push_sample_data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it "should call Slack API for issue events" do - slack.execute(@issues_sample_data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it "should call Slack API for merge requests events" do - slack.execute(@merge_sample_data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it 'should use the username as an option for slack when configured' do - slack.stub(username: username) - expect(Slack::Notifier).to receive(:new). - with(webhook_url, username: username). - and_return( - double(:slack_service).as_null_object - ) - slack.execute(push_sample_data) - end - - it 'should use the channel as an option when it is configured' do - slack.stub(channel: channel) - expect(Slack::Notifier).to receive(:new). - with(webhook_url, channel: channel). - and_return( - double(:slack_service).as_null_object - ) - slack.execute(push_sample_data) - end - end - - describe "Note events" do - let(:slack) { SlackService.new } - let(:user) { create(:user) } - let(:project) { create(:project, creator_id: user.id) } - let(:issue) { create(:issue, project: project) } - let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let(:snippet) { create(:project_snippet, project: project) } - let(:commit_note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') } - let(:merge_request_note) { create(:note_on_merge_request, noteable_id: merge_request.id, note: "merge request note") } - let(:issue_note) { create(:note_on_issue, noteable_id: issue.id, note: "issue note")} - let(:snippet_note) { create(:note_on_project_snippet, noteable_id: snippet.id, note: "snippet note") } - let(:webhook_url) { 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685' } - - before do - slack.stub( - project: project, - project_id: project.id, - service_hook: true, - webhook: webhook_url - ) - - WebMock.stub_request(:post, webhook_url) - end - - it "should call Slack API for commit comment events" do - data = Gitlab::NoteDataBuilder.build(commit_note, user) - slack.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it "should call Slack API for merge request comment events" do - data = Gitlab::NoteDataBuilder.build(merge_request_note, user) - slack.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it "should call Slack API for issue comment events" do - data = Gitlab::NoteDataBuilder.build(issue_note, user) - slack.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - - it "should call Slack API for snippet comment events" do - data = Gitlab::NoteDataBuilder.build(snippet_note, user) - slack.execute(data) - - expect(WebMock).to have_requested(:post, webhook_url).once - end - end -end diff --git a/spec/models/project_snippet_spec.rb b/spec/models/project_snippet_spec.rb deleted file mode 100644 index 3e8f106d27fd90e5c32fc839cc80db60ce6bf907..0000000000000000000000000000000000000000 --- a/spec/models/project_snippet_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string(255) -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string(255) -# expires_at :datetime -# type :string(255) -# visibility_level :integer default(0), not null -# - -require 'spec_helper' - -describe ProjectSnippet do - describe "Associations" do - it { is_expected.to belong_to(:project) } - end - - describe "Mass assignment" do - end - - describe "Validation" do - it { is_expected.to validate_presence_of(:project) } - end -end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb deleted file mode 100644 index 879a63dd9f954585e08e46ce4618ce62e6dd84c5..0000000000000000000000000000000000000000 --- a/spec/models/project_spec.rb +++ /dev/null @@ -1,360 +0,0 @@ -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) -# path :string(255) -# description :text -# created_at :datetime -# updated_at :datetime -# creator_id :integer -# issues_enabled :boolean default(TRUE), not null -# wall_enabled :boolean default(TRUE), not null -# merge_requests_enabled :boolean default(TRUE), not null -# wiki_enabled :boolean default(TRUE), not null -# namespace_id :integer -# issues_tracker :string(255) default("gitlab"), not null -# issues_tracker_id :string(255) -# snippets_enabled :boolean default(TRUE), not null -# last_activity_at :datetime -# import_url :string(255) -# visibility_level :integer default(0), not null -# archived :boolean default(FALSE), not null -# import_status :string(255) -# repository_size :float default(0.0) -# star_count :integer default(0), not null -# import_type :string(255) -# import_source :string(255) -# avatar :string(255) -# - -require 'spec_helper' - -describe Project do - describe 'Associations' do - it { is_expected.to belong_to(:group) } - it { is_expected.to belong_to(:namespace) } - it { is_expected.to belong_to(:creator).class_name('User') } - it { is_expected.to have_many(:users) } - it { is_expected.to have_many(:events).dependent(:destroy) } - it { is_expected.to have_many(:merge_requests).dependent(:destroy) } - it { is_expected.to have_many(:issues).dependent(:destroy) } - it { is_expected.to have_many(:milestones).dependent(:destroy) } - it { is_expected.to have_many(:project_members).dependent(:destroy) } - it { is_expected.to have_many(:notes).dependent(:destroy) } - it { is_expected.to have_many(:snippets).class_name('ProjectSnippet').dependent(:destroy) } - it { is_expected.to have_many(:deploy_keys_projects).dependent(:destroy) } - it { is_expected.to have_many(:deploy_keys) } - it { is_expected.to have_many(:hooks).dependent(:destroy) } - it { is_expected.to have_many(:protected_branches).dependent(:destroy) } - it { is_expected.to have_one(:forked_project_link).dependent(:destroy) } - it { is_expected.to have_one(:slack_service).dependent(:destroy) } - it { is_expected.to have_one(:pushover_service).dependent(:destroy) } - it { is_expected.to have_one(:asana_service).dependent(:destroy) } - end - - describe 'Mass assignment' do - end - - describe 'Validation' do - let!(:project) { create(:project) } - - it { is_expected.to validate_presence_of(:name) } - it { is_expected.to validate_uniqueness_of(:name).scoped_to(:namespace_id) } - it { is_expected.to ensure_length_of(:name).is_within(0..255) } - - it { is_expected.to validate_presence_of(:path) } - it { is_expected.to validate_uniqueness_of(:path).scoped_to(:namespace_id) } - it { is_expected.to ensure_length_of(:path).is_within(0..255) } - it { is_expected.to ensure_length_of(:description).is_within(0..2000) } - it { is_expected.to validate_presence_of(:creator) } - it { is_expected.to ensure_length_of(:issues_tracker_id).is_within(0..255) } - it { is_expected.to validate_presence_of(:namespace) } - - it 'should not allow new projects beyond user limits' do - project2 = build(:project) - allow(project2).to receive(:creator).and_return(double(can_create_project?: false, projects_limit: 0).as_null_object) - expect(project2).not_to be_valid - expect(project2.errors[:limit_reached].first).to match(/Your project limit is 0/) - end - end - - describe 'Respond to' do - it { is_expected.to respond_to(:url_to_repo) } - it { is_expected.to respond_to(:repo_exists?) } - it { is_expected.to respond_to(:satellite) } - it { is_expected.to respond_to(:update_merge_requests) } - it { is_expected.to respond_to(:execute_hooks) } - it { is_expected.to respond_to(:name_with_namespace) } - it { is_expected.to respond_to(:owner) } - it { is_expected.to respond_to(:path_with_namespace) } - end - - it 'should return valid url to repo' do - project = Project.new(path: 'somewhere') - expect(project.url_to_repo).to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + 'somewhere.git') - end - - it 'returns the full web URL for this repo' do - project = Project.new(path: 'somewhere') - expect(project.web_url).to eq("#{Gitlab.config.gitlab.url}/somewhere") - end - - it 'returns the web URL without the protocol for this repo' do - project = Project.new(path: 'somewhere') - expect(project.web_url_without_protocol).to eq("#{Gitlab.config.gitlab.url.split('://')[1]}/somewhere") - end - - describe 'last_activity methods' do - let(:project) { create(:project) } - let(:last_event) { double(created_at: Time.now) } - - describe 'last_activity' do - it 'should alias last_activity to last_event' do - project.stub(last_event: last_event) - expect(project.last_activity).to eq(last_event) - end - end - - describe 'last_activity_date' do - it 'returns the creation date of the project\'s last event if present' do - last_activity_event = create(:event, project: project) - expect(project.last_activity_at.to_i).to eq(last_event.created_at.to_i) - end - - it 'returns the project\'s last update date if it has no events' do - expect(project.last_activity_date).to eq(project.updated_at) - end - end - end - - describe :update_merge_requests do - let(:project) { create(:project) } - let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let(:key) { create(:key, user_id: project.owner.id) } - let(:prev_commit_id) { merge_request.commits.last.id } - let(:commit_id) { merge_request.commits.first.id } - - it 'should close merge request if last commit from source branch was pushed to target branch' do - project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.target_branch}", key.user) - merge_request.reload - expect(merge_request.merged?).to be_truthy - end - - it 'should update merge request commits with new one if pushed to source branch' do - project.update_merge_requests(prev_commit_id, commit_id, "refs/heads/#{merge_request.source_branch}", key.user) - merge_request.reload - expect(merge_request.last_commit.id).to eq(commit_id) - end - end - - describe :find_with_namespace do - context 'with namespace' do - before do - @group = create :group, name: 'gitlab' - @project = create(:project, name: 'gitlabhq', namespace: @group) - end - - it { expect(Project.find_with_namespace('gitlab/gitlabhq')).to eq(@project) } - it { expect(Project.find_with_namespace('gitlab-ci')).to be_nil } - end - end - - describe :to_param do - context 'with namespace' do - before do - @group = create :group, name: 'gitlab' - @project = create(:project, name: 'gitlabhq', namespace: @group) - end - - it { expect(@project.to_param).to eq('gitlabhq') } - end - end - - describe :repository do - let(:project) { create(:project) } - - it 'should return valid repo' do - expect(project.repository).to be_kind_of(Repository) - end - end - - describe :issue_exists? do - let(:project) { create(:project) } - let(:existed_issue) { create(:issue, project: project) } - let(:not_existed_issue) { create(:issue) } - let(:ext_project) { create(:redmine_project) } - - it 'should be true or if used internal tracker and issue exists' do - expect(project.issue_exists?(existed_issue.iid)).to be_truthy - end - - it 'should be false or if used internal tracker and issue not exists' do - expect(project.issue_exists?(not_existed_issue.iid)).to be_falsey - end - - it 'should always be true if used other tracker' do - expect(ext_project.issue_exists?(rand(100))).to be_truthy - end - end - - describe :default_issues_tracker? do - let(:project) { create(:project) } - let(:ext_project) { create(:redmine_project) } - - it "should be true if used internal tracker" do - expect(project.default_issues_tracker?).to be_truthy - end - - it "should be false if used other tracker" do - expect(ext_project.default_issues_tracker?).to be_falsey - end - end - - describe :can_have_issues_tracker_id? do - let(:project) { create(:project) } - let(:ext_project) { create(:redmine_project) } - - it 'should be true for projects with external issues tracker if issues enabled' do - expect(ext_project.can_have_issues_tracker_id?).to be_truthy - end - - it 'should be false for projects with internal issue tracker if issues enabled' do - expect(project.can_have_issues_tracker_id?).to be_falsey - end - - it 'should be always false if issues disabled' do - project.issues_enabled = false - ext_project.issues_enabled = false - - expect(project.can_have_issues_tracker_id?).to be_falsey - expect(ext_project.can_have_issues_tracker_id?).to be_falsey - end - end - - describe :open_branches do - let(:project) { create(:project) } - - before do - project.protected_branches.create(name: 'master') - end - - it { expect(project.open_branches.map(&:name)).to include('feature') } - it { expect(project.open_branches.map(&:name)).not_to include('master') } - end - - describe '#star_count' do - it 'counts stars from multiple users' do - user1 = create :user - user2 = create :user - project = create :project, :public - - expect(project.star_count).to eq(0) - - user1.toggle_star(project) - expect(project.reload.star_count).to eq(1) - - user2.toggle_star(project) - project.reload - expect(project.reload.star_count).to eq(2) - - user1.toggle_star(project) - project.reload - expect(project.reload.star_count).to eq(1) - - user2.toggle_star(project) - project.reload - expect(project.reload.star_count).to eq(0) - end - - it 'counts stars on the right project' do - user = create :user - project1 = create :project, :public - project2 = create :project, :public - - expect(project1.star_count).to eq(0) - expect(project2.star_count).to eq(0) - - user.toggle_star(project1) - project1.reload - project2.reload - expect(project1.star_count).to eq(1) - expect(project2.star_count).to eq(0) - - user.toggle_star(project1) - project1.reload - project2.reload - expect(project1.star_count).to eq(0) - expect(project2.star_count).to eq(0) - - user.toggle_star(project2) - project1.reload - project2.reload - expect(project1.star_count).to eq(0) - expect(project2.star_count).to eq(1) - - user.toggle_star(project2) - project1.reload - project2.reload - expect(project1.star_count).to eq(0) - expect(project2.star_count).to eq(0) - end - - it 'is decremented when an upvoter account is deleted' do - user = create :user - project = create :project, :public - user.toggle_star(project) - project.reload - expect(project.star_count).to eq(1) - user.destroy - project.reload - expect(project.star_count).to eq(0) - end - end - - describe :avatar_type do - let(:project) { create(:project) } - - it 'should be true if avatar is image' do - project.update_attribute(:avatar, 'uploads/avatar.png') - expect(project.avatar_type).to be_truthy - end - - it 'should be false if avatar is html page' do - project.update_attribute(:avatar, 'uploads/avatar.html') - expect(project.avatar_type).to eq(['only images allowed']) - end - end - - describe :avatar_url do - subject { project.avatar_url } - - let(:project) { create(:project) } - - context 'When avatar file is uploaded' do - before do - project.update_columns(avatar: 'uploads/avatar.png') - allow(project.avatar).to receive(:present?) { true } - end - - let(:avatar_path) do - "/uploads/project/avatar/#{project.id}/uploads/avatar.png" - end - - it { should eq "http://localhost#{avatar_path}" } - end - - context 'When avatar file in git' do - before do - allow(project).to receive(:avatar_in_git) { true } - end - - let(:avatar_path) do - "/#{project.namespace.name}/#{project.path}/avatar" - end - - it { should eq "http://localhost#{avatar_path}" } - end - end -end diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb deleted file mode 100644 index 19201cc15a7f474ef27e6f3c0d0db6f885b73f92..0000000000000000000000000000000000000000 --- a/spec/models/project_team_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -require "spec_helper" - -describe ProjectTeam do - let(:master) { create(:user) } - let(:reporter) { create(:user) } - let(:guest) { create(:user) } - let(:nonmember) { create(:user) } - - context 'personal project' do - let(:project) { create(:empty_project) } - - before do - project.team << [master, :master] - project.team << [reporter, :reporter] - project.team << [guest, :guest] - end - - describe 'members collection' do - it { expect(project.team.masters).to include(master) } - it { expect(project.team.masters).not_to include(guest) } - it { expect(project.team.masters).not_to include(reporter) } - it { expect(project.team.masters).not_to include(nonmember) } - end - - describe 'access methods' do - it { expect(project.team.master?(master)).to be_truthy } - it { expect(project.team.master?(guest)).to be_falsey } - it { expect(project.team.master?(reporter)).to be_falsey } - it { expect(project.team.master?(nonmember)).to be_falsey } - it { expect(project.team.member?(nonmember)).to be_falsey } - it { expect(project.team.member?(guest)).to be_truthy } - end - end - - context 'group project' do - let(:group) { create(:group) } - let(:project) { create(:empty_project, group: group) } - - before do - group.add_user(master, Gitlab::Access::MASTER) - group.add_user(reporter, Gitlab::Access::REPORTER) - group.add_user(guest, Gitlab::Access::GUEST) - - # If user is a group and a project member - GitLab uses highest permission - # So we add group guest as master and add group master as guest - # to this project to test highest access - project.team << [guest, :master] - project.team << [master, :guest] - end - - describe 'members collection' do - it { expect(project.team.reporters).to include(reporter) } - it { expect(project.team.masters).to include(master) } - it { expect(project.team.masters).to include(guest) } - it { expect(project.team.masters).not_to include(reporter) } - it { expect(project.team.masters).not_to include(nonmember) } - end - - describe 'access methods' do - it { expect(project.team.reporter?(reporter)).to be_truthy } - it { expect(project.team.master?(master)).to be_truthy } - it { expect(project.team.master?(guest)).to be_truthy } - it { expect(project.team.master?(reporter)).to be_falsey } - it { expect(project.team.master?(nonmember)).to be_falsey } - it { expect(project.team.member?(nonmember)).to be_falsey } - it { expect(project.team.member?(guest)).to be_truthy } - end - end -end - diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb deleted file mode 100644 index 2acdb7dfddcba5af30abeda55bd60ece92488a13..0000000000000000000000000000000000000000 --- a/spec/models/project_wiki_spec.rb +++ /dev/null @@ -1,244 +0,0 @@ -require "spec_helper" - -describe ProjectWiki do - let(:project) { create(:empty_project) } - let(:repository) { project.repository } - let(:user) { project.owner } - let(:gitlab_shell) { Gitlab::Shell.new } - let(:project_wiki) { ProjectWiki.new(project, user) } - - subject { project_wiki } - before { project_wiki.wiki } - - describe "#path_with_namespace" do - it "returns the project path with namespace with the .wiki extension" do - expect(subject.path_with_namespace).to eq(project.path_with_namespace + ".wiki") - end - end - - describe "#url_to_repo" do - it "returns the correct ssh url to the repo" do - expect(subject.url_to_repo).to eq(gitlab_shell.url_to_repo(subject.path_with_namespace)) - end - end - - describe "#ssh_url_to_repo" do - it "equals #url_to_repo" do - expect(subject.ssh_url_to_repo).to eq(subject.url_to_repo) - end - end - - describe "#http_url_to_repo" do - it "provides the full http url to the repo" do - gitlab_url = Gitlab.config.gitlab.url - repo_http_url = "#{gitlab_url}/#{subject.path_with_namespace}.git" - expect(subject.http_url_to_repo).to eq(repo_http_url) - end - end - - describe "#wiki" do - it "contains a Gollum::Wiki instance" do - expect(subject.wiki).to be_a Gollum::Wiki - end - - it "creates a new wiki repo if one does not yet exist" do - expect(project_wiki.create_page("index", "test content")).to be_truthy - end - - it "raises CouldNotCreateWikiError if it can't create the wiki repository" do - allow(project_wiki).to receive(:init_repo).and_return(false) - expect { project_wiki.send(:create_repo!) }.to raise_exception(ProjectWiki::CouldNotCreateWikiError) - end - end - - describe "#empty?" do - context "when the wiki repository is empty" do - before do - allow_any_instance_of(Gitlab::Shell).to receive(:add_repository) do - create_temp_repo("#{Rails.root}/tmp/test-git-base-path/non-existant.wiki.git") - end - allow(project).to receive(:path_with_namespace).and_return("non-existant") - end - - describe '#empty?' do - subject { super().empty? } - it { is_expected.to be_truthy } - end - end - - context "when the wiki has pages" do - before do - project_wiki.create_page("index", "This is an awesome new Gollum Wiki") - end - - describe '#empty?' do - subject { super().empty? } - it { is_expected.to be_falsey } - end - end - end - - describe "#pages" do - before do - create_page("index", "This is an awesome new Gollum Wiki") - @pages = subject.pages - end - - after do - destroy_page(@pages.first.page) - end - - it "returns an array of WikiPage instances" do - expect(@pages.first).to be_a WikiPage - end - - it "returns the correct number of pages" do - expect(@pages.count).to eq(1) - end - end - - describe "#find_page" do - before do - create_page("index page", "This is an awesome Gollum Wiki") - end - - after do - destroy_page(subject.pages.first.page) - end - - it "returns the latest version of the page if it exists" do - page = subject.find_page("index page") - expect(page.title).to eq("index page") - end - - it "returns nil if the page does not exist" do - expect(subject.find_page("non-existant")).to eq(nil) - end - - it "can find a page by slug" do - page = subject.find_page("index-page") - expect(page.title).to eq("index page") - end - - it "returns a WikiPage instance" do - page = subject.find_page("index page") - expect(page).to be_a WikiPage - end - end - - describe '#find_file' do - before do - file = Gollum::File.new(subject.wiki) - allow_any_instance_of(Gollum::Wiki). - to receive(:file).with('image.jpg', 'master', true). - and_return(file) - allow_any_instance_of(Gollum::File). - to receive(:mime_type). - and_return('image/jpeg') - allow_any_instance_of(Gollum::Wiki). - to receive(:file).with('non-existant', 'master', true). - and_return(nil) - end - - after do - allow_any_instance_of(Gollum::Wiki).to receive(:file).and_call_original - allow_any_instance_of(Gollum::File).to receive(:mime_type).and_call_original - end - - it 'returns the latest version of the file if it exists' do - file = subject.find_file('image.jpg') - expect(file.mime_type).to eq('image/jpeg') - end - - it 'returns nil if the page does not exist' do - expect(subject.find_file('non-existant')).to eq(nil) - end - - it 'returns a Gollum::File instance' do - file = subject.find_file('image.jpg') - expect(file).to be_a Gollum::File - end - end - - describe "#create_page" do - after do - destroy_page(subject.pages.first.page) - end - - it "creates a new wiki page" do - expect(subject.create_page("test page", "this is content")).not_to eq(false) - expect(subject.pages.count).to eq(1) - end - - it "returns false when a duplicate page exists" do - subject.create_page("test page", "content") - expect(subject.create_page("test page", "content")).to eq(false) - end - - it "stores an error message when a duplicate page exists" do - 2.times { subject.create_page("test page", "content") } - expect(subject.error_message).to match(/Duplicate page:/) - end - - it "sets the correct commit message" do - subject.create_page("test page", "some content", :markdown, "commit message") - expect(subject.pages.first.page.version.message).to eq("commit message") - end - end - - describe "#update_page" do - before do - create_page("update-page", "some content") - @gollum_page = subject.wiki.paged("update-page") - subject.update_page(@gollum_page, "some other content", :markdown, "updated page") - @page = subject.pages.first.page - end - - after do - destroy_page(@page) - end - - it "updates the content of the page" do - expect(@page.raw_data).to eq("some other content") - end - - it "sets the correct commit message" do - expect(@page.version.message).to eq("updated page") - end - end - - describe "#delete_page" do - before do - create_page("index", "some content") - @page = subject.wiki.paged("index") - end - - it "deletes the page" do - subject.delete_page(@page) - expect(subject.pages.count).to eq(0) - end - end - - private - - def create_temp_repo(path) - FileUtils.mkdir_p path - system(*%W(git init --quiet --bare -- #{path})) - end - - def remove_temp_repo(path) - FileUtils.rm_rf path - end - - def commit_details - commit = {name: user.name, email: user.email, message: "test commit"} - end - - def create_page(name, content) - subject.wiki.write_page(name, :markdown, content, commit_details) - end - - def destroy_page(page) - subject.wiki.delete_page(page, commit_details) - end -end diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb deleted file mode 100644 index 1e6937b536c418581c8800c7ab348c6116cc46c1..0000000000000000000000000000000000000000 --- a/spec/models/protected_branch_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -# == Schema Information -# -# Table name: protected_branches -# -# id :integer not null, primary key -# project_id :integer not null -# name :string(255) not null -# created_at :datetime -# updated_at :datetime -# developers_can_push :boolean default(FALSE), not null -# - -require 'spec_helper' - -describe ProtectedBranch do - describe 'Associations' do - it { is_expected.to belong_to(:project) } - end - - describe "Mass assignment" do - end - - describe 'Validation' do - it { is_expected.to validate_presence_of(:project) } - it { is_expected.to validate_presence_of(:name) } - end -end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb deleted file mode 100644 index f41e5a97ca34d1b9de26c90ae607b0c884efc567..0000000000000000000000000000000000000000 --- a/spec/models/repository_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe Repository do - include RepoHelpers - - let(:repository) { create(:project).repository } - - describe :branch_names_contains do - subject { repository.branch_names_contains(sample_commit.id) } - - it { is_expected.to include('master') } - it { is_expected.not_to include('feature') } - it { is_expected.not_to include('fix') } - end - - describe :tag_names_contains do - subject { repository.tag_names_contains(sample_commit.id) } - - it { is_expected.to include('v1.1.0') } - it { is_expected.not_to include('v1.0.0') } - end - - describe :last_commit_for_path do - subject { repository.last_commit_for_path(sample_commit.id, '.gitignore').id } - - it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') } - end -end diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb deleted file mode 100644 index 735652aea78e496cedfe441133218de6f66fec96..0000000000000000000000000000000000000000 --- a/spec/models/service_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# template :boolean default(FALSE) -# push_events :boolean default(TRUE) -# issues_events :boolean default(TRUE) -# merge_requests_events :boolean default(TRUE) -# tag_push_events :boolean default(TRUE) -# - -require 'spec_helper' - -describe Service do - - describe "Associations" do - it { is_expected.to belong_to :project } - it { is_expected.to have_one :service_hook } - end - - describe "Mass assignment" do - end - - describe "Test Button" do - before do - @service = Service.new - end - - describe "Testable" do - let (:project) { create :project } - - before do - @service.stub( - project: project - ) - @testable = @service.can_test? - end - - describe :can_test do - it { expect(@testable).to eq(true) } - end - end - - describe "With commits" do - let (:project) { create :project } - - before do - @service.stub( - project: project - ) - @testable = @service.can_test? - end - - describe :can_test do - it { expect(@testable).to eq(true) } - end - end - end - - describe "Template" do - describe "for pushover service" do - let(:service_template) { - PushoverService.create(template: true, properties: {device: 'MyDevice', sound: 'mic', priority: 4, api_key: '123456789'}) - } - let(:project) { create(:project) } - - describe 'should be prefilled for projects pushover service' do - before do - service_template - project.build_missing_services - end - - it "should have all fields prefilled" do - service = project.pushover_service - expect(service.template).to eq(false) - expect(service.device).to eq('MyDevice') - expect(service.sound).to eq('mic') - expect(service.priority).to eq(4) - expect(service.api_key).to eq('123456789') - end - end - end - end -end diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb deleted file mode 100644 index e37dcc752306869e34bff90528367d313069e600..0000000000000000000000000000000000000000 --- a/spec/models/snippet_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string(255) -# content :text -# author_id :integer not null -# project_id :integer -# created_at :datetime -# updated_at :datetime -# file_name :string(255) -# expires_at :datetime -# type :string(255) -# visibility_level :integer default(0), not null -# - -require 'spec_helper' - -describe Snippet do - describe "Associations" do - it { is_expected.to belong_to(:author).class_name('User') } - it { is_expected.to have_many(:notes).dependent(:destroy) } - end - - describe "Mass assignment" do - end - - describe "Validation" do - it { is_expected.to validate_presence_of(:author) } - - it { is_expected.to validate_presence_of(:title) } - it { is_expected.to ensure_length_of(:title).is_within(0..255) } - - it { is_expected.to validate_presence_of(:file_name) } - it { is_expected.to ensure_length_of(:title).is_within(0..255) } - - it { is_expected.to validate_presence_of(:content) } - end -end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb deleted file mode 100644 index 24384e8bf2277dbc4cd54f81ee27076d0a9db6d1..0000000000000000000000000000000000000000 --- a/spec/models/user_spec.rb +++ /dev/null @@ -1,532 +0,0 @@ -# == Schema Information -# -# Table name: users -# -# id :integer not null, primary key -# email :string(255) default(""), not null -# encrypted_password :string(255) default(""), not null -# reset_password_token :string(255) -# reset_password_sent_at :datetime -# remember_created_at :datetime -# sign_in_count :integer default(0) -# current_sign_in_at :datetime -# last_sign_in_at :datetime -# current_sign_in_ip :string(255) -# last_sign_in_ip :string(255) -# created_at :datetime -# updated_at :datetime -# name :string(255) -# admin :boolean default(FALSE), not null -# projects_limit :integer default(10) -# skype :string(255) default(""), not null -# linkedin :string(255) default(""), not null -# twitter :string(255) default(""), not null -# authentication_token :string(255) -# theme_id :integer default(1), not null -# bio :string(255) -# failed_attempts :integer default(0) -# locked_at :datetime -# username :string(255) -# can_create_group :boolean default(TRUE), not null -# can_create_team :boolean default(TRUE), not null -# state :string(255) -# color_scheme_id :integer default(1), not null -# notification_level :integer default(1), not null -# password_expires_at :datetime -# created_by_id :integer -# last_credential_check_at :datetime -# avatar :string(255) -# confirmation_token :string(255) -# confirmed_at :datetime -# confirmation_sent_at :datetime -# unconfirmed_email :string(255) -# hide_no_ssh_key :boolean default(FALSE) -# website_url :string(255) default(""), not null -# github_access_token :string(255) -# gitlab_access_token :string(255) -# notification_email :string(255) -# hide_no_password :boolean default(FALSE) -# password_automatically_set :boolean default(FALSE) -# bitbucket_access_token :string(255) -# bitbucket_access_token_secret :string(255) -# - -require 'spec_helper' - -describe User do - describe "Associations" do - it { is_expected.to have_one(:namespace) } - it { is_expected.to have_many(:snippets).class_name('Snippet').dependent(:destroy) } - it { is_expected.to have_many(:project_members).dependent(:destroy) } - it { is_expected.to have_many(:groups) } - it { is_expected.to have_many(:keys).dependent(:destroy) } - it { is_expected.to have_many(:events).class_name('Event').dependent(:destroy) } - it { is_expected.to have_many(:recent_events).class_name('Event') } - it { is_expected.to have_many(:issues).dependent(:destroy) } - it { is_expected.to have_many(:notes).dependent(:destroy) } - it { is_expected.to have_many(:assigned_issues).dependent(:destroy) } - it { is_expected.to have_many(:merge_requests).dependent(:destroy) } - it { is_expected.to have_many(:assigned_merge_requests).dependent(:destroy) } - it { is_expected.to have_many(:identities).dependent(:destroy) } - end - - describe "Mass assignment" do - end - - describe 'validations' do - it { is_expected.to validate_presence_of(:username) } - it { is_expected.to validate_presence_of(:projects_limit) } - it { is_expected.to validate_numericality_of(:projects_limit) } - it { is_expected.to allow_value(0).for(:projects_limit) } - it { is_expected.not_to allow_value(-1).for(:projects_limit) } - - it { is_expected.to ensure_length_of(:bio).is_within(0..255) } - - describe 'email' do - it 'accepts info@example.com' do - user = build(:user, email: 'info@example.com') - expect(user).to be_valid - end - - it 'accepts info+test@example.com' do - user = build(:user, email: 'info+test@example.com') - expect(user).to be_valid - end - - it "accepts o'reilly@example.com" do - user = build(:user, email: "o'reilly@example.com") - expect(user).to be_valid - end - - it 'rejects test@test@example.com' do - user = build(:user, email: 'test@test@example.com') - expect(user).to be_invalid - end - - it 'rejects mailto:test@example.com' do - user = build(:user, email: 'mailto:test@example.com') - expect(user).to be_invalid - end - - it "rejects lol!'+=?><#$%^&*()@gmail.com" do - user = build(:user, email: "lol!'+=?><#$%^&*()@gmail.com") - expect(user).to be_invalid - end - end - end - - describe "Respond to" do - it { is_expected.to respond_to(:is_admin?) } - it { is_expected.to respond_to(:name) } - it { is_expected.to respond_to(:private_token) } - end - - describe '#generate_password' do - it "should execute callback when force_random_password specified" do - user = build(:user, force_random_password: true) - expect(user).to receive(:generate_password) - user.save - end - - it "should not generate password by default" do - user = create(:user, password: 'abcdefghe') - expect(user.password).to eq('abcdefghe') - end - - it "should generate password when forcing random password" do - allow(Devise).to receive(:friendly_token).and_return('123456789') - user = create(:user, password: 'abcdefg', force_random_password: true) - expect(user.password).to eq('12345678') - end - end - - describe 'authentication token' do - it "should have authentication token" do - user = create(:user) - expect(user.authentication_token).not_to be_blank - end - end - - describe 'projects' do - before do - @user = create :user - @project = create :project, namespace: @user.namespace - @project_2 = create :project, group: create(:group) # Grant MASTER access to the user - @project_3 = create :project, group: create(:group) # Grant DEVELOPER access to the user - - @project_2.team << [@user, :master] - @project_3.team << [@user, :developer] - end - - it { expect(@user.authorized_projects).to include(@project) } - it { expect(@user.authorized_projects).to include(@project_2) } - it { expect(@user.authorized_projects).to include(@project_3) } - it { expect(@user.owned_projects).to include(@project) } - it { expect(@user.owned_projects).not_to include(@project_2) } - it { expect(@user.owned_projects).not_to include(@project_3) } - it { expect(@user.personal_projects).to include(@project) } - it { expect(@user.personal_projects).not_to include(@project_2) } - it { expect(@user.personal_projects).not_to include(@project_3) } - end - - describe 'groups' do - before do - @user = create :user - @group = create :group - @group.add_owner(@user) - end - - it { expect(@user.several_namespaces?).to be_truthy } - it { expect(@user.authorized_groups).to eq([@group]) } - it { expect(@user.owned_groups).to eq([@group]) } - end - - describe 'group multiple owners' do - before do - @user = create :user - @user2 = create :user - @group = create :group - @group.add_owner(@user) - - @group.add_user(@user2, GroupMember::OWNER) - end - - it { expect(@user2.several_namespaces?).to be_truthy } - end - - describe 'namespaced' do - before do - @user = create :user - @project = create :project, namespace: @user.namespace - end - - it { expect(@user.several_namespaces?).to be_falsey } - end - - describe 'blocking user' do - let(:user) { create(:user, name: 'John Smith') } - - it "should block user" do - user.block - expect(user.blocked?).to be_truthy - end - end - - describe 'filter' do - before do - User.delete_all - @user = create :user - @admin = create :user, admin: true - @blocked = create :user, state: :blocked - end - - it { expect(User.filter("admins")).to eq([@admin]) } - it { expect(User.filter("blocked")).to eq([@blocked]) } - it { expect(User.filter("wop")).to include(@user, @admin, @blocked) } - it { expect(User.filter(nil)).to include(@user, @admin) } - end - - describe :not_in_project do - before do - User.delete_all - @user = create :user - @project = create :project - end - - it { expect(User.not_in_project(@project)).to include(@user, @project.owner) } - end - - describe 'user creation' do - describe 'normal user' do - let(:user) { create(:user, name: 'John Smith') } - - it { expect(user.is_admin?).to be_falsey } - it { expect(user.require_ssh_key?).to be_truthy } - it { expect(user.can_create_group?).to be_truthy } - it { expect(user.can_create_project?).to be_truthy } - it { expect(user.first_name).to eq('John') } - end - - describe 'with defaults' do - let(:user) { User.new } - - it "should apply defaults to user" do - expect(user.projects_limit).to eq(Gitlab.config.gitlab.default_projects_limit) - expect(user.can_create_group).to eq(Gitlab.config.gitlab.default_can_create_group) - expect(user.theme_id).to eq(Gitlab.config.gitlab.default_theme) - end - end - - describe 'with default overrides' do - let(:user) { User.new(projects_limit: 123, can_create_group: false, can_create_team: true, theme_id: Gitlab::Theme::BASIC) } - - it "should apply defaults to user" do - expect(user.projects_limit).to eq(123) - expect(user.can_create_group).to be_falsey - expect(user.theme_id).to eq(Gitlab::Theme::BASIC) - end - end - end - - describe 'search' do - let(:user1) { create(:user, username: 'James', email: 'james@testing.com') } - let(:user2) { create(:user, username: 'jameson', email: 'jameson@example.com') } - - it "should be case insensitive" do - expect(User.search(user1.username.upcase).to_a).to eq([user1]) - expect(User.search(user1.username.downcase).to_a).to eq([user1]) - expect(User.search(user2.username.upcase).to_a).to eq([user2]) - expect(User.search(user2.username.downcase).to_a).to eq([user2]) - expect(User.search(user1.username.downcase).to_a.count).to eq(2) - expect(User.search(user2.username.downcase).to_a.count).to eq(1) - end - end - - describe 'by_username_or_id' do - let(:user1) { create(:user, username: 'foo') } - - it "should get the correct user" do - expect(User.by_username_or_id(user1.id)).to eq(user1) - expect(User.by_username_or_id('foo')).to eq(user1) - expect(User.by_username_or_id(-1)).to be_nil - expect(User.by_username_or_id('bar')).to be_nil - end - end - - describe '.by_login' do - let(:username) { 'John' } - let!(:user) { create(:user, username: username) } - - it 'should get the correct user' do - expect(User.by_login(user.email.upcase)).to eq user - expect(User.by_login(user.email)).to eq user - expect(User.by_login(username.downcase)).to eq user - expect(User.by_login(username)).to eq user - expect(User.by_login(nil)).to be_nil - expect(User.by_login('')).to be_nil - end - end - - describe 'all_ssh_keys' do - it { is_expected.to have_many(:keys).dependent(:destroy) } - - it "should have all ssh keys" do - user = create :user - key = create :key, key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD33bWLBxu48Sev9Fert1yzEO4WGcWglWF7K/AwblIUFselOt/QdOL9DSjpQGxLagO1s9wl53STIO8qGS4Ms0EJZyIXOEFMjFJ5xmjSy+S37By4sG7SsltQEHMxtbtFOaW5LV2wCrX+rUsRNqLMamZjgjcPO0/EgGCXIGMAYW4O7cwGZdXWYIhQ1Vwy+CsVMDdPkPgBXqK7nR/ey8KMs8ho5fMNgB5hBw/AL9fNGhRw3QTD6Q12Nkhl4VZES2EsZqlpNnJttnPdp847DUsT6yuLRlfiQfz5Cn9ysHFdXObMN5VYIiPFwHeYCZp1X2S4fDZooRE8uOLTfxWHPXwrhqSH", user_id: user.id - - expect(user.all_ssh_keys).to include(key.key) - end - end - - describe :avatar_type do - let(:user) { create(:user) } - - it "should be true if avatar is image" do - user.update_attribute(:avatar, 'uploads/avatar.png') - expect(user.avatar_type).to be_truthy - end - - it "should be false if avatar is html page" do - user.update_attribute(:avatar, 'uploads/avatar.html') - expect(user.avatar_type).to eq(["only images allowed"]) - end - end - - describe :requires_ldap_check? do - let(:user) { User.new } - - it 'is false when LDAP is disabled' do - # Create a condition which would otherwise cause 'true' to be returned - user.stub(ldap_user?: true) - user.last_credential_check_at = nil - expect(user.requires_ldap_check?).to be_falsey - end - - context 'when LDAP is enabled' do - before { Gitlab.config.ldap.stub(enabled: true) } - - it 'is false for non-LDAP users' do - user.stub(ldap_user?: false) - expect(user.requires_ldap_check?).to be_falsey - end - - context 'and when the user is an LDAP user' do - before { user.stub(ldap_user?: true) } - - it 'is true when the user has never had an LDAP check before' do - user.last_credential_check_at = nil - expect(user.requires_ldap_check?).to be_truthy - end - - it 'is true when the last LDAP check happened over 1 hour ago' do - user.last_credential_check_at = 2.hours.ago - expect(user.requires_ldap_check?).to be_truthy - end - end - end - end - - describe :ldap_user? do - it "is true if provider name starts with ldap" do - user = create(:omniauth_user, provider: 'ldapmain') - expect( user.ldap_user? ).to be_truthy - end - - it "is false for other providers" do - user = create(:omniauth_user, provider: 'other-provider') - expect( user.ldap_user? ).to be_falsey - end - - it "is false if no extern_uid is provided" do - user = create(:omniauth_user, extern_uid: nil) - expect( user.ldap_user? ).to be_falsey - end - end - - describe :ldap_identity do - it "returns ldap identity" do - user = create :omniauth_user - expect(user.ldap_identity.provider).not_to be_empty - end - end - - describe '#full_website_url' do - let(:user) { create(:user) } - - it 'begins with http if website url omits it' do - user.website_url = 'test.com' - - expect(user.full_website_url).to eq 'http://test.com' - end - - it 'begins with http if website url begins with http' do - user.website_url = 'http://test.com' - - expect(user.full_website_url).to eq 'http://test.com' - end - - it 'begins with https if website url begins with https' do - user.website_url = 'https://test.com' - - expect(user.full_website_url).to eq 'https://test.com' - end - end - - describe '#short_website_url' do - let(:user) { create(:user) } - - it 'does not begin with http if website url omits it' do - user.website_url = 'test.com' - - expect(user.short_website_url).to eq 'test.com' - end - - it 'does not begin with http if website url begins with http' do - user.website_url = 'http://test.com' - - expect(user.short_website_url).to eq 'test.com' - end - - it 'does not begin with https if website url begins with https' do - user.website_url = 'https://test.com' - - expect(user.short_website_url).to eq 'test.com' - end - end - - describe "#starred?" do - it "determines if user starred a project" do - user = create :user - project1 = create :project, :public - project2 = create :project, :public - - expect(user.starred?(project1)).to be_falsey - expect(user.starred?(project2)).to be_falsey - - star1 = UsersStarProject.create!(project: project1, user: user) - expect(user.starred?(project1)).to be_truthy - expect(user.starred?(project2)).to be_falsey - - star2 = UsersStarProject.create!(project: project2, user: user) - expect(user.starred?(project1)).to be_truthy - expect(user.starred?(project2)).to be_truthy - - star1.destroy - expect(user.starred?(project1)).to be_falsey - expect(user.starred?(project2)).to be_truthy - - star2.destroy - expect(user.starred?(project1)).to be_falsey - expect(user.starred?(project2)).to be_falsey - end - end - - describe "#toggle_star" do - it "toggles stars" do - user = create :user - project = create :project, :public - - expect(user.starred?(project)).to be_falsey - user.toggle_star(project) - expect(user.starred?(project)).to be_truthy - user.toggle_star(project) - expect(user.starred?(project)).to be_falsey - end - end - - describe "#sort" do - before do - User.delete_all - @user = create :user, created_at: Date.today, last_sign_in_at: Date.today, name: 'Alpha' - @user1 = create :user, created_at: Date.today - 1, last_sign_in_at: Date.today - 1, name: 'Omega' - end - - it "sorts users as recently_signed_in" do - expect(User.sort('recent_sign_in').first).to eq(@user) - end - - it "sorts users as late_signed_in" do - expect(User.sort('oldest_sign_in').first).to eq(@user1) - end - - it "sorts users as recently_created" do - expect(User.sort('created_desc').first).to eq(@user) - end - - it "sorts users as late_created" do - expect(User.sort('created_asc').first).to eq(@user1) - end - - it "sorts users by name when nil is passed" do - expect(User.sort(nil).first).to eq(@user) - end - end - - describe "#contributed_projects_ids" do - - subject { create(:user) } - let!(:project1) { create(:project) } - let!(:project2) { create(:project, forked_from_project: project3) } - let!(:project3) { create(:project) } - let!(:merge_request) { create(:merge_request, source_project: project2, target_project: project3, author: subject) } - let!(:push_event) { create(:event, action: Event::PUSHED, project: project1, target: project1, author: subject) } - let!(:merge_event) { create(:event, action: Event::CREATED, project: project3, target: merge_request, author: subject) } - - before do - project1.team << [subject, :master] - project2.team << [subject, :master] - end - - it "includes IDs for projects the user has pushed to" do - expect(subject.contributed_projects_ids).to include(project1.id) - end - - it "includes IDs for projects the user has had merge requests merged into" do - expect(subject.contributed_projects_ids).to include(project3.id) - end - - it "doesn't include IDs for unrelated projects" do - expect(subject.contributed_projects_ids).not_to include(project2.id) - end - end -end diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb deleted file mode 100644 index fceb7668cac4cf22dcb1b73d97b021ba2137057c..0000000000000000000000000000000000000000 --- a/spec/models/wiki_page_spec.rb +++ /dev/null @@ -1,210 +0,0 @@ -require "spec_helper" - -describe WikiPage do - let(:project) { create(:empty_project) } - let(:user) { project.owner } - let(:wiki) { ProjectWiki.new(project, user) } - - subject { WikiPage.new(wiki) } - - describe "#initialize" do - context "when initialized with an existing gollum page" do - before do - create_page("test page", "test content") - @page = wiki.wiki.paged("test page") - @wiki_page = WikiPage.new(wiki, @page, true) - end - - it "sets the slug attribute" do - expect(@wiki_page.slug).to eq("test-page") - end - - it "sets the title attribute" do - expect(@wiki_page.title).to eq("test page") - end - - it "sets the formatted content attribute" do - expect(@wiki_page.content).to eq("test content") - end - - it "sets the format attribute" do - expect(@wiki_page.format).to eq(:markdown) - end - - it "sets the message attribute" do - expect(@wiki_page.message).to eq("test commit") - end - - it "sets the version attribute" do - expect(@wiki_page.version).to be_a Gollum::Git::Commit - end - end - end - - describe "validations" do - before do - subject.attributes = {title: 'title', content: 'content'} - end - - it "validates presence of title" do - subject.attributes.delete(:title) - expect(subject.valid?).to be_falsey - end - - it "validates presence of content" do - subject.attributes.delete(:content) - expect(subject.valid?).to be_falsey - end - end - - before do - @wiki_attr = {title: "Index", content: "Home Page", format: "markdown"} - end - - describe "#create" do - after do - destroy_page("Index") - end - - context "with valid attributes" do - it "saves the wiki page" do - subject.create(@wiki_attr) - expect(wiki.find_page("Index")).not_to be_nil - end - - it "returns true" do - expect(subject.create(@wiki_attr)).to eq(true) - end - end - end - - describe "dot in the title" do - let(:title) { 'Index v1.2.3' } - - before do - @wiki_attr = {title: title, content: "Home Page", format: "markdown"} - end - - describe "#create" do - after do - destroy_page(title) - end - - context "with valid attributes" do - it "saves the wiki page" do - subject.create(@wiki_attr) - expect(wiki.find_page(title)).not_to be_nil - end - - it "returns true" do - expect(subject.create(@wiki_attr)).to eq(true) - end - end - end - - describe "#update" do - before do - create_page(title, "content") - @page = wiki.find_page(title) - end - - it "updates the content of the page" do - @page.update("new content") - @page = wiki.find_page(title) - end - - it "returns true" do - expect(@page.update("more content")).to be_truthy - end - end - end - - describe "#update" do - before do - create_page("Update", "content") - @page = wiki.find_page("Update") - end - - after do - destroy_page("Update") - end - - context "with valid attributes" do - it "updates the content of the page" do - @page.update("new content") - @page = wiki.find_page("Update") - end - - it "returns true" do - expect(@page.update("more content")).to be_truthy - end - end - end - - describe "#destroy" do - before do - create_page("Delete Page", "content") - @page = wiki.find_page("Delete Page") - end - - it "should delete the page" do - @page.delete - expect(wiki.pages).to be_empty - end - - it "should return true" do - expect(@page.delete).to eq(true) - end - end - - describe "#versions" do - before do - create_page("Update", "content") - @page = wiki.find_page("Update") - end - - after do - destroy_page("Update") - end - - it "returns an array of all commits for the page" do - 3.times { |i| @page.update("content #{i}") } - expect(@page.versions.count).to eq(4) - end - end - - describe "#title" do - before do - create_page("Title", "content") - @page = wiki.find_page("Title") - end - - after do - destroy_page("Title") - end - - it "should be replace a hyphen to a space" do - @page.title = "Import-existing-repositories-into-GitLab" - expect(@page.title).to eq("Import existing repositories into GitLab") - end - end - - private - - def remove_temp_repo(path) - FileUtils.rm_rf path - end - - def commit_details - commit = {name: user.name, email: user.email, message: "test commit"} - end - - def create_page(name, content) - wiki.wiki.write_page(name, :markdown, content, commit_details) - end - - def destroy_page(title) - page = wiki.wiki.paged(title) - wiki.wiki.delete_page(page, commit_details) - end -end diff --git a/spec/requests/api/api_helpers_spec.rb b/spec/requests/api/api_helpers_spec.rb deleted file mode 100644 index 20cb30a39bb208cc11d05795b21fd57f6c687a48..0000000000000000000000000000000000000000 --- a/spec/requests/api/api_helpers_spec.rb +++ /dev/null @@ -1,173 +0,0 @@ -require 'spec_helper' - -describe API, api: true do - include API::APIHelpers - include ApiHelpers - let(:user) { create(:user) } - let(:admin) { create(:admin) } - let(:key) { create(:key, user: user) } - - let(:params) { {} } - let(:env) { {} } - - def set_env(token_usr, identifier) - clear_env - clear_param - env[API::APIHelpers::PRIVATE_TOKEN_HEADER] = token_usr.private_token - env[API::APIHelpers::SUDO_HEADER] = identifier - end - - def set_param(token_usr, identifier) - clear_env - clear_param - params[API::APIHelpers::PRIVATE_TOKEN_PARAM] = token_usr.private_token - params[API::APIHelpers::SUDO_PARAM] = identifier - end - - def clear_env - env.delete(API::APIHelpers::PRIVATE_TOKEN_HEADER) - env.delete(API::APIHelpers::SUDO_HEADER) - end - - def clear_param - params.delete(API::APIHelpers::PRIVATE_TOKEN_PARAM) - params.delete(API::APIHelpers::SUDO_PARAM) - end - - def error!(message, status) - raise Exception - end - - describe ".current_user" do - it "should return nil for an invalid token" do - env[API::APIHelpers::PRIVATE_TOKEN_HEADER] = 'invalid token' - allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false } - expect(current_user).to be_nil - end - - it "should return nil for a user without access" do - env[API::APIHelpers::PRIVATE_TOKEN_HEADER] = user.private_token - Gitlab::UserAccess.stub(allowed?: false) - expect(current_user).to be_nil - end - - it "should leave user as is when sudo not specified" do - env[API::APIHelpers::PRIVATE_TOKEN_HEADER] = user.private_token - expect(current_user).to eq(user) - clear_env - params[API::APIHelpers::PRIVATE_TOKEN_PARAM] = user.private_token - expect(current_user).to eq(user) - end - - it "should change current user to sudo when admin" do - set_env(admin, user.id) - expect(current_user).to eq(user) - set_param(admin, user.id) - expect(current_user).to eq(user) - set_env(admin, user.username) - expect(current_user).to eq(user) - set_param(admin, user.username) - expect(current_user).to eq(user) - end - - it "should throw an error when the current user is not an admin and attempting to sudo" do - set_env(user, admin.id) - expect { current_user }.to raise_error - set_param(user, admin.id) - expect { current_user }.to raise_error - set_env(user, admin.username) - expect { current_user }.to raise_error - set_param(user, admin.username) - expect { current_user }.to raise_error - end - - it "should throw an error when the user cannot be found for a given id" do - id = user.id + admin.id - expect(user.id).not_to eq(id) - expect(admin.id).not_to eq(id) - set_env(admin, id) - expect { current_user }.to raise_error - - set_param(admin, id) - expect { current_user }.to raise_error - end - - it "should throw an error when the user cannot be found for a given username" do - username = "#{user.username}#{admin.username}" - expect(user.username).not_to eq(username) - expect(admin.username).not_to eq(username) - set_env(admin, username) - expect { current_user }.to raise_error - - set_param(admin, username) - expect { current_user }.to raise_error - end - - it "should handle sudo's to oneself" do - set_env(admin, admin.id) - expect(current_user).to eq(admin) - set_param(admin, admin.id) - expect(current_user).to eq(admin) - set_env(admin, admin.username) - expect(current_user).to eq(admin) - set_param(admin, admin.username) - expect(current_user).to eq(admin) - end - - it "should handle multiple sudo's to oneself" do - set_env(admin, user.id) - expect(current_user).to eq(user) - expect(current_user).to eq(user) - set_env(admin, user.username) - expect(current_user).to eq(user) - expect(current_user).to eq(user) - - set_param(admin, user.id) - expect(current_user).to eq(user) - expect(current_user).to eq(user) - set_param(admin, user.username) - expect(current_user).to eq(user) - expect(current_user).to eq(user) - end - - it "should handle multiple sudo's to oneself using string ids" do - set_env(admin, user.id.to_s) - expect(current_user).to eq(user) - expect(current_user).to eq(user) - - set_param(admin, user.id.to_s) - expect(current_user).to eq(user) - expect(current_user).to eq(user) - end - end - - describe '.sudo_identifier' do - it "should return integers when input is an int" do - set_env(admin, '123') - expect(sudo_identifier).to eq(123) - set_env(admin, '0001234567890') - expect(sudo_identifier).to eq(1234567890) - - set_param(admin, '123') - expect(sudo_identifier).to eq(123) - set_param(admin, '0001234567890') - expect(sudo_identifier).to eq(1234567890) - end - - it "should return string when input is an is not an int" do - set_env(admin, '12.30') - expect(sudo_identifier).to eq("12.30") - set_env(admin, 'hello') - expect(sudo_identifier).to eq('hello') - set_env(admin, ' 123') - expect(sudo_identifier).to eq(' 123') - - set_param(admin, '12.30') - expect(sudo_identifier).to eq("12.30") - set_param(admin, 'hello') - expect(sudo_identifier).to eq('hello') - set_param(admin, ' 123') - expect(sudo_identifier).to eq(' 123') - end - end -end diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb deleted file mode 100644 index f40d68b75a4ea2399760d6714e57f55b618d2e11..0000000000000000000000000000000000000000 --- a/spec/requests/api/branches_spec.rb +++ /dev/null @@ -1,170 +0,0 @@ -require 'spec_helper' -require 'mime/types' - -describe API::API, api: true do - include ApiHelpers - - let(:user) { create(:user) } - let(:user2) { create(:user) } - let!(:project) { create(:project, creator_id: user.id) } - let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) } - let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) } - let!(:branch_name) { 'feature' } - let!(:branch_sha) { '0b4bc9a49b562e85de7cc9e834518ea6828729b9' } - - describe "GET /projects/:id/repository/branches" do - it "should return an array of project branches" do - get api("/projects/#{project.id}/repository/branches", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['name']).to eq(project.repository.branch_names.first) - end - end - - describe "GET /projects/:id/repository/branches/:branch" do - it "should return the branch information for a single branch" do - get api("/projects/#{project.id}/repository/branches/#{branch_name}", user) - expect(response.status).to eq(200) - - expect(json_response['name']).to eq(branch_name) - expect(json_response['commit']['id']).to eq(branch_sha) - expect(json_response['protected']).to eq(false) - end - - it "should return a 403 error if guest" do - get api("/projects/#{project.id}/repository/branches", user2) - expect(response.status).to eq(403) - end - - it "should return a 404 error if branch is not available" do - get api("/projects/#{project.id}/repository/branches/unknown", user) - expect(response.status).to eq(404) - end - end - - describe "PUT /projects/:id/repository/branches/:branch/protect" do - it "should protect a single branch" do - put api("/projects/#{project.id}/repository/branches/#{branch_name}/protect", user) - expect(response.status).to eq(200) - - expect(json_response['name']).to eq(branch_name) - expect(json_response['commit']['id']).to eq(branch_sha) - expect(json_response['protected']).to eq(true) - end - - it "should return a 404 error if branch not found" do - put api("/projects/#{project.id}/repository/branches/unknown/protect", user) - expect(response.status).to eq(404) - end - - it "should return a 403 error if guest" do - put api("/projects/#{project.id}/repository/branches/#{branch_name}/protect", user2) - expect(response.status).to eq(403) - end - - it "should return success when protect branch again" do - put api("/projects/#{project.id}/repository/branches/#{branch_name}/protect", user) - put api("/projects/#{project.id}/repository/branches/#{branch_name}/protect", user) - expect(response.status).to eq(200) - end - end - - describe "PUT /projects/:id/repository/branches/:branch/unprotect" do - it "should unprotect a single branch" do - put api("/projects/#{project.id}/repository/branches/#{branch_name}/unprotect", user) - expect(response.status).to eq(200) - - expect(json_response['name']).to eq(branch_name) - expect(json_response['commit']['id']).to eq(branch_sha) - expect(json_response['protected']).to eq(false) - end - - it "should return success when unprotect branch" do - put api("/projects/#{project.id}/repository/branches/unknown/unprotect", user) - expect(response.status).to eq(404) - end - - it "should return success when unprotect branch again" do - put api("/projects/#{project.id}/repository/branches/#{branch_name}/unprotect", user) - put api("/projects/#{project.id}/repository/branches/#{branch_name}/unprotect", user) - expect(response.status).to eq(200) - end - end - - describe "POST /projects/:id/repository/branches" do - it "should create a new branch" do - post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'feature1', - ref: branch_sha - - expect(response.status).to eq(201) - - expect(json_response['name']).to eq('feature1') - expect(json_response['commit']['id']).to eq(branch_sha) - end - - it "should deny for user without push access" do - post api("/projects/#{project.id}/repository/branches", user2), - branch_name: branch_name, - ref: branch_sha - expect(response.status).to eq(403) - end - - it 'should return 400 if branch name is invalid' do - post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'new design', - ref: branch_sha - expect(response.status).to eq(400) - expect(json_response['message']).to eq('Branch name invalid') - end - - it 'should return 400 if branch already exists' do - post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'new_design1', - ref: branch_sha - expect(response.status).to eq(201) - - post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'new_design1', - ref: branch_sha - expect(response.status).to eq(400) - expect(json_response['message']).to eq('Branch already exists') - end - - it 'should return 400 if ref name is invalid' do - post api("/projects/#{project.id}/repository/branches", user), - branch_name: 'new_design3', - ref: 'foo' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('Invalid reference name') - end - end - - describe "DELETE /projects/:id/repository/branches/:branch" do - before { Repository.any_instance.stub(rm_branch: true) } - - it "should remove branch" do - delete api("/projects/#{project.id}/repository/branches/#{branch_name}", user) - expect(response.status).to eq(200) - expect(json_response['branch_name']).to eq(branch_name) - end - - it 'should return 404 if branch not exists' do - delete api("/projects/#{project.id}/repository/branches/foobar", user) - expect(response.status).to eq(404) - end - - it "should remove protected branch" do - project.protected_branches.create(name: branch_name) - delete api("/projects/#{project.id}/repository/branches/#{branch_name}", user) - expect(response.status).to eq(405) - expect(json_response['message']).to eq('Protected branch cant be removed') - end - - it "should not remove HEAD branch" do - delete api("/projects/#{project.id}/repository/branches/master", user) - expect(response.status).to eq(405) - expect(json_response['message']).to eq('Cannot remove HEAD branch') - end - end -end diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb deleted file mode 100644 index 9ea60e1a4adb597c230dd5148df8a02dc93737a0..0000000000000000000000000000000000000000 --- a/spec/requests/api/commits_spec.rb +++ /dev/null @@ -1,149 +0,0 @@ -require 'spec_helper' -require 'mime/types' - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let(:user2) { create(:user) } - let!(:project) { create(:project, creator_id: user.id) } - let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) } - let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) } - let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') } - - before { project.team << [user, :reporter] } - - describe "GET /projects/:id/repository/commits" do - context "authorized user" do - before { project.team << [user2, :reporter] } - - it "should return project commits" do - get api("/projects/#{project.id}/repository/commits", user) - expect(response.status).to eq(200) - - expect(json_response).to be_an Array - expect(json_response.first['id']).to eq(project.repository.commit.id) - end - end - - context "unauthorized user" do - it "should not return project commits" do - get api("/projects/#{project.id}/repository/commits") - expect(response.status).to eq(401) - end - end - end - - describe "GET /projects:id/repository/commits/:sha" do - context "authorized user" do - it "should return a commit by sha" do - get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user) - expect(response.status).to eq(200) - expect(json_response['id']).to eq(project.repository.commit.id) - expect(json_response['title']).to eq(project.repository.commit.title) - end - - it "should return a 404 error if not found" do - get api("/projects/#{project.id}/repository/commits/invalid_sha", user) - expect(response.status).to eq(404) - end - end - - context "unauthorized user" do - it "should not return the selected commit" do - get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}") - expect(response.status).to eq(401) - end - end - end - - describe "GET /projects:id/repository/commits/:sha/diff" do - context "authorized user" do - before { project.team << [user2, :reporter] } - - it "should return the diff of the selected commit" do - get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user) - expect(response.status).to eq(200) - - expect(json_response).to be_an Array - expect(json_response.length).to be >= 1 - expect(json_response.first.keys).to include "diff" - end - - it "should return a 404 error if invalid commit" do - get api("/projects/#{project.id}/repository/commits/invalid_sha/diff", user) - expect(response.status).to eq(404) - end - end - - context "unauthorized user" do - it "should not return the diff of the selected commit" do - get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff") - expect(response.status).to eq(401) - end - end - end - - describe 'GET /projects:id/repository/commits/:sha/comments' do - context 'authorized user' do - it 'should return merge_request comments' do - get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['note']).to eq('a comment on a commit') - expect(json_response.first['author']['id']).to eq(user.id) - end - - it 'should return a 404 error if merge_request_id not found' do - get api("/projects/#{project.id}/repository/commits/1234ab/comments", user) - expect(response.status).to eq(404) - end - end - - context 'unauthorized user' do - it 'should not return the diff of the selected commit' do - get api("/projects/#{project.id}/repository/commits/1234ab/comments") - expect(response.status).to eq(401) - end - end - end - - describe 'POST /projects:id/repository/commits/:sha/comments' do - context 'authorized user' do - it 'should return comment' do - post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment' - expect(response.status).to eq(201) - expect(json_response['note']).to eq('My comment') - expect(json_response['path']).to be_nil - expect(json_response['line']).to be_nil - expect(json_response['line_type']).to be_nil - end - - it 'should return the inline comment' do - post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.diffs.first.new_path, line: 7, line_type: 'new' - expect(response.status).to eq(201) - expect(json_response['note']).to eq('My comment') - expect(json_response['path']).to eq(project.repository.commit.diffs.first.new_path) - expect(json_response['line']).to eq(7) - expect(json_response['line_type']).to eq('new') - end - - it 'should return 400 if note is missing' do - post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user) - expect(response.status).to eq(400) - end - - it 'should return 404 if note is attached to non existent commit' do - post api("/projects/#{project.id}/repository/commits/1234ab/comments", user), note: 'My comment' - expect(response.status).to eq(404) - end - end - - context 'unauthorized user' do - it 'should not return the diff of the selected commit' do - post api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments") - expect(response.status).to eq(401) - end - end - end -end diff --git a/spec/requests/api/doorkeeper_access_spec.rb b/spec/requests/api/doorkeeper_access_spec.rb deleted file mode 100644 index 39949a9042286cafc791a6554d79b5dadbf9223f..0000000000000000000000000000000000000000 --- a/spec/requests/api/doorkeeper_access_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - - let!(:user) { create(:user) } - let!(:application) { Doorkeeper::Application.create!(:name => "MyApp", :redirect_uri => "https://app.com", :owner => user) } - let!(:token) { Doorkeeper::AccessToken.create! :application_id => application.id, :resource_owner_id => user.id } - - - describe "when unauthenticated" do - it "returns authentication success" do - get api("/user"), :access_token => token.token - expect(response.status).to eq(200) - end - end - - describe "when token invalid" do - it "returns authentication error" do - get api("/user"), :access_token => "123a" - expect(response.status).to eq(401) - end - end - - describe "authorization by private token" do - it "returns authentication success" do - get api("/user", user) - expect(response.status).to eq(200) - end - end -end diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb deleted file mode 100644 index bab8888a631277b9c79360405c3fa5bdf6c50ac2..0000000000000000000000000000000000000000 --- a/spec/requests/api/files_spec.rb +++ /dev/null @@ -1,164 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let!(:project) { create(:project, namespace: user.namespace ) } - let(:file_path) { 'files/ruby/popen.rb' } - - before { project.team << [user, :developer] } - - describe "GET /projects/:id/repository/files" do - it "should return file info" do - params = { - file_path: file_path, - ref: 'master', - } - - get api("/projects/#{project.id}/repository/files", user), params - expect(response.status).to eq(200) - expect(json_response['file_path']).to eq(file_path) - expect(json_response['file_name']).to eq('popen.rb') - expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n") - end - - it "should return a 400 bad request if no params given" do - get api("/projects/#{project.id}/repository/files", user) - expect(response.status).to eq(400) - end - - it "should return a 404 if such file does not exist" do - params = { - file_path: 'app/models/application.rb', - ref: 'master', - } - - get api("/projects/#{project.id}/repository/files", user), params - expect(response.status).to eq(404) - end - end - - describe "POST /projects/:id/repository/files" do - let(:valid_params) { - { - file_path: 'newfile.rb', - branch_name: 'master', - content: 'puts 8', - commit_message: 'Added newfile' - } - } - - it "should create a new file in project repo" do - Gitlab::Satellite::NewFileAction.any_instance.stub( - commit!: true, - ) - - post api("/projects/#{project.id}/repository/files", user), valid_params - expect(response.status).to eq(201) - expect(json_response['file_path']).to eq('newfile.rb') - end - - it "should return a 400 bad request if no params given" do - post api("/projects/#{project.id}/repository/files", user) - expect(response.status).to eq(400) - end - - it "should return a 400 if satellite fails to create file" do - Gitlab::Satellite::NewFileAction.any_instance.stub( - commit!: false, - ) - - post api("/projects/#{project.id}/repository/files", user), valid_params - expect(response.status).to eq(400) - end - end - - describe "PUT /projects/:id/repository/files" do - let(:valid_params) { - { - file_path: file_path, - branch_name: 'master', - content: 'puts 8', - commit_message: 'Changed file' - } - } - - it "should update existing file in project repo" do - Gitlab::Satellite::EditFileAction.any_instance.stub( - commit!: true, - ) - - put api("/projects/#{project.id}/repository/files", user), valid_params - expect(response.status).to eq(200) - expect(json_response['file_path']).to eq(file_path) - end - - it "should return a 400 bad request if no params given" do - put api("/projects/#{project.id}/repository/files", user) - expect(response.status).to eq(400) - end - - it 'should return a 400 if the checkout fails' do - Gitlab::Satellite::EditFileAction.any_instance.stub(:commit!) - .and_raise(Gitlab::Satellite::CheckoutFailed) - - put api("/projects/#{project.id}/repository/files", user), valid_params - expect(response.status).to eq(400) - - ref = valid_params[:branch_name] - expect(response.body).to match("ref '#{ref}' could not be checked out") - end - - it 'should return a 409 if the file was not modified' do - Gitlab::Satellite::EditFileAction.any_instance.stub(:commit!) - .and_raise(Gitlab::Satellite::CommitFailed) - - put api("/projects/#{project.id}/repository/files", user), valid_params - expect(response.status).to eq(409) - expect(response.body).to match("Maybe there was nothing to commit?") - end - - it 'should return a 409 if the push fails' do - Gitlab::Satellite::EditFileAction.any_instance.stub(:commit!) - .and_raise(Gitlab::Satellite::PushFailed) - - put api("/projects/#{project.id}/repository/files", user), valid_params - expect(response.status).to eq(409) - expect(response.body).to match("Maybe the file was changed by another process?") - end - end - - describe "DELETE /projects/:id/repository/files" do - let(:valid_params) { - { - file_path: file_path, - branch_name: 'master', - commit_message: 'Changed file' - } - } - - it "should delete existing file in project repo" do - Gitlab::Satellite::DeleteFileAction.any_instance.stub( - commit!: true, - ) - - delete api("/projects/#{project.id}/repository/files", user), valid_params - expect(response.status).to eq(200) - expect(json_response['file_path']).to eq(file_path) - end - - it "should return a 400 bad request if no params given" do - delete api("/projects/#{project.id}/repository/files", user) - expect(response.status).to eq(400) - end - - it "should return a 400 if satellite fails to create file" do - Gitlab::Satellite::DeleteFileAction.any_instance.stub( - commit!: false, - ) - - delete api("/projects/#{project.id}/repository/files", user), valid_params - expect(response.status).to eq(400) - end - end -end diff --git a/spec/requests/api/fork_spec.rb b/spec/requests/api/fork_spec.rb deleted file mode 100644 index fb3ff552c8d412440c4b4b6263d748cecb08ec77..0000000000000000000000000000000000000000 --- a/spec/requests/api/fork_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:user3) { create(:user) } - let(:admin) { create(:admin) } - let(:project) { - create(:project, creator_id: user.id, - namespace: user.namespace) - } - let(:project_user2) { - create(:project_member, user: user2, - project: project, - access_level: ProjectMember::GUEST) - } - - describe 'POST /projects/fork/:id' do - before { project_user2 } - before { user3 } - - context 'when authenticated' do - it 'should fork if user has sufficient access to project' do - post api("/projects/fork/#{project.id}", user2) - expect(response.status).to eq(201) - expect(json_response['name']).to eq(project.name) - expect(json_response['path']).to eq(project.path) - expect(json_response['owner']['id']).to eq(user2.id) - expect(json_response['namespace']['id']).to eq(user2.namespace.id) - expect(json_response['forked_from_project']['id']).to eq(project.id) - end - - it 'should fork if user is admin' do - post api("/projects/fork/#{project.id}", admin) - expect(response.status).to eq(201) - expect(json_response['name']).to eq(project.name) - expect(json_response['path']).to eq(project.path) - expect(json_response['owner']['id']).to eq(admin.id) - expect(json_response['namespace']['id']).to eq(admin.namespace.id) - expect(json_response['forked_from_project']['id']).to eq(project.id) - end - - it 'should fail on missing project access for the project to fork' do - post api("/projects/fork/#{project.id}", user3) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Project Not Found') - end - - it 'should fail if forked project exists in the user namespace' do - post api("/projects/fork/#{project.id}", user) - expect(response.status).to eq(409) - expect(json_response['message']['base']).to eq(['Invalid fork destination']) - expect(json_response['message']['name']).to eq(['has already been taken']) - expect(json_response['message']['path']).to eq(['has already been taken']) - end - - it 'should fail if project to fork from does not exist' do - post api('/projects/fork/424242', user) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Project Not Found') - end - end - - context 'when unauthenticated' do - it 'should return authentication error' do - post api("/projects/fork/#{project.id}") - expect(response.status).to eq(401) - expect(json_response['message']).to eq('401 Unauthorized') - end - end - end -end diff --git a/spec/requests/api/group_members_spec.rb b/spec/requests/api/group_members_spec.rb deleted file mode 100644 index 8ba6876a95b112b5f66c28467699edca39f223bd..0000000000000000000000000000000000000000 --- a/spec/requests/api/group_members_spec.rb +++ /dev/null @@ -1,199 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - - let(:owner) { create(:user) } - let(:reporter) { create(:user) } - let(:developer) { create(:user) } - let(:master) { create(:user) } - let(:guest) { create(:user) } - let(:stranger) { create(:user) } - - let!(:group_with_members) do - group = create(:group) - group.add_users([reporter.id], GroupMember::REPORTER) - group.add_users([developer.id], GroupMember::DEVELOPER) - group.add_users([master.id], GroupMember::MASTER) - group.add_users([guest.id], GroupMember::GUEST) - group - end - - let!(:group_no_members) { create(:group) } - - before do - group_with_members.add_owner owner - group_no_members.add_owner owner - end - - describe "GET /groups/:id/members" do - context "when authenticated as user that is part or the group" do - it "each user: should return an array of members groups of group3" do - [owner, master, developer, reporter, guest].each do |user| - get api("/groups/#{group_with_members.id}/members", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.size).to eq(5) - expect(json_response.find { |e| e['id']==owner.id }['access_level']).to eq(GroupMember::OWNER) - expect(json_response.find { |e| e['id']==reporter.id }['access_level']).to eq(GroupMember::REPORTER) - expect(json_response.find { |e| e['id']==developer.id }['access_level']).to eq(GroupMember::DEVELOPER) - expect(json_response.find { |e| e['id']==master.id }['access_level']).to eq(GroupMember::MASTER) - expect(json_response.find { |e| e['id']==guest.id }['access_level']).to eq(GroupMember::GUEST) - end - end - - it "users not part of the group should get access error" do - get api("/groups/#{group_with_members.id}/members", stranger) - expect(response.status).to eq(403) - end - end - end - - describe "POST /groups/:id/members" do - context "when not a member of the group" do - it "should not add guest as member of group_no_members when adding being done by person outside the group" do - post api("/groups/#{group_no_members.id}/members", reporter), user_id: guest.id, access_level: GroupMember::MASTER - expect(response.status).to eq(403) - end - end - - context "when a member of the group" do - it "should return ok and add new member" do - new_user = create(:user) - - expect { - post api("/groups/#{group_no_members.id}/members", owner), - user_id: new_user.id, access_level: GroupMember::MASTER - }.to change { group_no_members.members.count }.by(1) - - expect(response.status).to eq(201) - expect(json_response['name']).to eq(new_user.name) - expect(json_response['access_level']).to eq(GroupMember::MASTER) - end - - it "should not allow guest to modify group members" do - new_user = create(:user) - - expect { - post api("/groups/#{group_with_members.id}/members", guest), - user_id: new_user.id, access_level: GroupMember::MASTER - }.not_to change { group_with_members.members.count } - - expect(response.status).to eq(403) - end - - it "should return error if member already exists" do - post api("/groups/#{group_with_members.id}/members", owner), user_id: master.id, access_level: GroupMember::MASTER - expect(response.status).to eq(409) - end - - it "should return a 400 error when user id is not given" do - post api("/groups/#{group_no_members.id}/members", owner), access_level: GroupMember::MASTER - expect(response.status).to eq(400) - end - - it "should return a 400 error when access level is not given" do - post api("/groups/#{group_no_members.id}/members", owner), user_id: master.id - expect(response.status).to eq(400) - end - - it "should return a 422 error when access level is not known" do - post api("/groups/#{group_no_members.id}/members", owner), user_id: master.id, access_level: 1234 - expect(response.status).to eq(422) - end - end - end - - describe 'PUT /groups/:id/members/:user_id' do - context 'when not a member of the group' do - it 'should return a 409 error if the user is not a group member' do - put( - api("/groups/#{group_no_members.id}/members/#{developer.id}", - owner), access_level: GroupMember::MASTER - ) - expect(response.status).to eq(404) - end - end - - context 'when a member of the group' do - it 'should return ok and update member access level' do - put( - api("/groups/#{group_with_members.id}/members/#{reporter.id}", - owner), - access_level: GroupMember::MASTER - ) - - expect(response.status).to eq(200) - - get api("/groups/#{group_with_members.id}/members", owner) - json_reporter = json_response.find do |e| - e['id'] == reporter.id - end - - expect(json_reporter['access_level']).to eq(GroupMember::MASTER) - end - - it 'should not allow guest to modify group members' do - put( - api("/groups/#{group_with_members.id}/members/#{developer.id}", - guest), - access_level: GroupMember::MASTER - ) - - expect(response.status).to eq(403) - - get api("/groups/#{group_with_members.id}/members", owner) - json_developer = json_response.find do |e| - e['id'] == developer.id - end - - expect(json_developer['access_level']).to eq(GroupMember::DEVELOPER) - end - - it 'should return a 400 error when access level is not given' do - put( - api("/groups/#{group_with_members.id}/members/#{master.id}", owner) - ) - expect(response.status).to eq(400) - end - - it 'should return a 422 error when access level is not known' do - put( - api("/groups/#{group_with_members.id}/members/#{master.id}", owner), - access_level: 1234 - ) - expect(response.status).to eq(422) - end - end - end - - describe "DELETE /groups/:id/members/:user_id" do - context "when not a member of the group" do - it "should not delete guest's membership of group_with_members" do - random_user = create(:user) - delete api("/groups/#{group_with_members.id}/members/#{owner.id}", random_user) - expect(response.status).to eq(403) - end - end - - context "when a member of the group" do - it "should delete guest's membership of group" do - expect { - delete api("/groups/#{group_with_members.id}/members/#{guest.id}", owner) - }.to change { group_with_members.members.count }.by(-1) - - expect(response.status).to eq(200) - end - - it "should return a 404 error when user id is not known" do - delete api("/groups/#{group_with_members.id}/members/1328", owner) - expect(response.status).to eq(404) - end - - it "should not allow guest to modify group members" do - delete api("/groups/#{group_with_members.id}/members/#{master.id}", guest) - expect(response.status).to eq(403) - end - end - end -end diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb deleted file mode 100644 index d963dbac9f1196b285bfd57d3cd3539f89749fe3..0000000000000000000000000000000000000000 --- a/spec/requests/api/groups_spec.rb +++ /dev/null @@ -1,187 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - - let(:user1) { create(:user) } - let(:user2) { create(:user) } - let(:admin) { create(:admin) } - let!(:group1) { create(:group) } - let!(:group2) { create(:group) } - - before do - group1.add_owner(user1) - group2.add_owner(user2) - end - - describe "GET /groups" do - context "when unauthenticated" do - it "should return authentication error" do - get api("/groups") - expect(response.status).to eq(401) - end - end - - context "when authenticated as user" do - it "normal user: should return an array of groups of user1" do - get api("/groups", user1) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['name']).to eq(group1.name) - end - end - - context "when authenticated as admin" do - it "admin: should return an array of all groups" do - get api("/groups", admin) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(2) - end - end - end - - describe "GET /groups/:id" do - context "when authenticated as user" do - it "should return one of user1's groups" do - get api("/groups/#{group1.id}", user1) - expect(response.status).to eq(200) - json_response['name'] == group1.name - end - - it "should not return a non existing group" do - get api("/groups/1328", user1) - expect(response.status).to eq(404) - end - - it "should not return a group not attached to user1" do - get api("/groups/#{group2.id}", user1) - expect(response.status).to eq(403) - end - end - - context "when authenticated as admin" do - it "should return any existing group" do - get api("/groups/#{group2.id}", admin) - expect(response.status).to eq(200) - json_response['name'] == group2.name - end - - it "should not return a non existing group" do - get api("/groups/1328", admin) - expect(response.status).to eq(404) - end - end - - context 'when using group path in URL' do - it 'should return any existing group' do - get api("/groups/#{group1.path}", admin) - expect(response.status).to eq(200) - json_response['name'] == group2.name - end - - it 'should not return a non existing group' do - get api('/groups/unknown', admin) - expect(response.status).to eq(404) - end - - it 'should not return a group not attached to user1' do - get api("/groups/#{group2.path}", user1) - expect(response.status).to eq(403) - end - end - end - - describe "POST /groups" do - context "when authenticated as user" do - it "should not create group" do - post api("/groups", user1), attributes_for(:group) - expect(response.status).to eq(403) - end - end - - context "when authenticated as admin" do - it "should create group" do - post api("/groups", admin), attributes_for(:group) - expect(response.status).to eq(201) - end - - it "should not create group, duplicate" do - post api("/groups", admin), {name: "Duplicate Test", path: group2.path} - expect(response.status).to eq(400) - expect(response.message).to eq("Bad Request") - end - - it "should return 400 bad request error if name not given" do - post api("/groups", admin), {path: group2.path} - expect(response.status).to eq(400) - end - - it "should return 400 bad request error if path not given" do - post api("/groups", admin), { name: 'test' } - expect(response.status).to eq(400) - end - end - end - - describe "DELETE /groups/:id" do - context "when authenticated as user" do - it "should remove group" do - delete api("/groups/#{group1.id}", user1) - expect(response.status).to eq(200) - end - - it "should not remove a group if not an owner" do - user3 = create(:user) - group1.add_user(user3, Gitlab::Access::MASTER) - delete api("/groups/#{group1.id}", user3) - expect(response.status).to eq(403) - end - - it "should not remove a non existing group" do - delete api("/groups/1328", user1) - expect(response.status).to eq(404) - end - - it "should not remove a group not attached to user1" do - delete api("/groups/#{group2.id}", user1) - expect(response.status).to eq(403) - end - end - - context "when authenticated as admin" do - it "should remove any existing group" do - delete api("/groups/#{group2.id}", admin) - expect(response.status).to eq(200) - end - - it "should not remove a non existing group" do - delete api("/groups/1328", admin) - expect(response.status).to eq(404) - end - end - end - - describe "POST /groups/:id/projects/:project_id" do - let(:project) { create(:project) } - before(:each) do - Projects::TransferService.any_instance.stub(execute: true) - allow(Project).to receive(:find).and_return(project) - end - - context "when authenticated as user" do - it "should not transfer project to group" do - post api("/groups/#{group1.id}/projects/#{project.id}", user2) - expect(response.status).to eq(403) - end - end - - context "when authenticated as admin" do - it "should transfer project to group" do - post api("/groups/#{group1.id}/projects/#{project.id}", admin) - expect(response.status).to eq(201) - end - end - end -end diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb deleted file mode 100644 index 4c7d15d6594e8766b7dbb701b4d39a808190ec35..0000000000000000000000000000000000000000 --- a/spec/requests/api/internal_spec.rb +++ /dev/null @@ -1,229 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let(:key) { create(:key, user: user) } - let(:project) { create(:project) } - let(:secret_token) { File.read Rails.root.join('.gitlab_shell_secret') } - - describe "GET /internal/check", no_db: true do - it do - get api("/internal/check"), secret_token: secret_token - - expect(response.status).to eq(200) - expect(json_response['api_version']).to eq(API::API.version) - end - end - - describe "GET /internal/broadcast_message" do - context "broadcast message exists" do - let!(:broadcast_message) { create(:broadcast_message, starts_at: Time.now.yesterday, ends_at: Time.now.tomorrow ) } - - it do - get api("/internal/broadcast_message"), secret_token: secret_token - - expect(response.status).to eq(200) - expect(json_response["message"]).to eq(broadcast_message.message) - end - end - - context "broadcast message doesn't exist" do - it do - get api("/internal/broadcast_message"), secret_token: secret_token - - expect(response.status).to eq(200) - expect(json_response).to be_empty - end - end - end - - describe "GET /internal/discover" do - it do - get(api("/internal/discover"), key_id: key.id, secret_token: secret_token) - - expect(response.status).to eq(200) - - expect(json_response['name']).to eq(user.name) - end - end - - describe "POST /internal/allowed" do - context "access granted" do - before do - project.team << [user, :developer] - end - - context "git pull" do - it do - pull(key, project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_truthy - end - end - - context "git push" do - it do - push(key, project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_truthy - end - end - end - - context "access denied" do - before do - project.team << [user, :guest] - end - - context "git pull" do - it do - pull(key, project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_falsey - end - end - - context "git push" do - it do - push(key, project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_falsey - end - end - end - - context "blocked user" do - let(:personal_project) { create(:project, namespace: user.namespace) } - - before do - user.block - end - - context "git pull" do - it do - pull(key, personal_project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_falsey - end - end - - context "git push" do - it do - push(key, personal_project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_falsey - end - end - end - - context "archived project" do - let(:personal_project) { create(:project, namespace: user.namespace) } - - before do - project.team << [user, :developer] - project.archive! - end - - context "git pull" do - it do - pull(key, project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_truthy - end - end - - context "git push" do - it do - push(key, project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_falsey - end - end - end - - context "deploy key" do - let(:key) { create(:deploy_key) } - - context "added to project" do - before do - key.projects << project - end - - it do - archive(key, project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_truthy - end - end - - context "not added to project" do - it do - archive(key, project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_falsey - end - end - end - - context 'project does not exist' do - it do - pull(key, OpenStruct.new(path_with_namespace: 'gitlab/notexists')) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_falsey - end - end - - context 'user does not exist' do - it do - pull(OpenStruct.new(id: 0), project) - - expect(response.status).to eq(200) - expect(json_response["status"]).to be_falsey - end - end - end - - def pull(key, project) - post( - api("/internal/allowed"), - key_id: key.id, - project: project.path_with_namespace, - action: 'git-upload-pack', - secret_token: secret_token - ) - end - - def push(key, project) - post( - api("/internal/allowed"), - changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master', - key_id: key.id, - project: project.path_with_namespace, - action: 'git-receive-pack', - secret_token: secret_token - ) - end - - def archive(key, project) - post( - api("/internal/allowed"), - ref: 'master', - key_id: key.id, - project: project.path_with_namespace, - action: 'git-upload-archive', - secret_token: secret_token - ) - end -end diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb deleted file mode 100644 index b6b0427debf93666406cf5180af659bf6af273be..0000000000000000000000000000000000000000 --- a/spec/requests/api/issues_spec.rb +++ /dev/null @@ -1,330 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let!(:project) { create(:project, namespace: user.namespace ) } - let!(:closed_issue) do - create :closed_issue, - author: user, - assignee: user, - project: project, - state: :closed, - milestone: milestone - end - let!(:issue) do - create :issue, - author: user, - assignee: user, - project: project, - milestone: milestone - end - let!(:label) do - create(:label, title: 'label', color: '#FFAABB', project: project) - end - let!(:label_link) { create(:label_link, label: label, target: issue) } - let!(:milestone) { create(:milestone, title: '1.0.0', project: project) } - let!(:empty_milestone) do - create(:milestone, title: '2.0.0', project: project) - end - - before { project.team << [user, :reporter] } - - describe "GET /issues" do - context "when unauthenticated" do - it "should return authentication error" do - get api("/issues") - expect(response.status).to eq(401) - end - end - - context "when authenticated" do - it "should return an array of issues" do - get api("/issues", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['title']).to eq(issue.title) - end - - it "should add pagination headers" do - get api("/issues?per_page=3", user) - expect(response.headers['Link']).to eq( - '; rel="first", ; rel="last"' - ) - end - - it 'should return an array of closed issues' do - get api('/issues?state=closed', user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['id']).to eq(closed_issue.id) - end - - it 'should return an array of opened issues' do - get api('/issues?state=opened', user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['id']).to eq(issue.id) - end - - it 'should return an array of all issues' do - get api('/issues?state=all', user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(2) - expect(json_response.first['id']).to eq(issue.id) - expect(json_response.second['id']).to eq(closed_issue.id) - end - - it 'should return an array of labeled issues' do - get api("/issues?labels=#{label.title}", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['labels']).to eq([label.title]) - end - - it 'should return an array of labeled issues when at least one label matches' do - get api("/issues?labels=#{label.title},foo,bar", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['labels']).to eq([label.title]) - end - - it 'should return an empty array if no issue matches labels' do - get api('/issues?labels=foo,bar', user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(0) - end - - it 'should return an array of labeled issues matching given state' do - get api("/issues?labels=#{label.title}&state=opened", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['labels']).to eq([label.title]) - expect(json_response.first['state']).to eq('opened') - end - - it 'should return an empty array if no issue matches labels and state filters' do - get api("/issues?labels=#{label.title}&state=closed", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(0) - end - end - end - - describe "GET /projects/:id/issues" do - let(:base_url) { "/projects/#{project.id}" } - let(:title) { milestone.title } - - it "should return project issues" do - get api("#{base_url}/issues", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['title']).to eq(issue.title) - end - - it 'should return an array of labeled project issues' do - get api("#{base_url}/issues?labels=#{label.title}", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['labels']).to eq([label.title]) - end - - it 'should return an array of labeled project issues when at least one label matches' do - get api("#{base_url}/issues?labels=#{label.title},foo,bar", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['labels']).to eq([label.title]) - end - - it 'should return an empty array if no project issue matches labels' do - get api("#{base_url}/issues?labels=foo,bar", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(0) - end - - it 'should return an empty array if no issue matches milestone' do - get api("#{base_url}/issues?milestone=#{empty_milestone.title}", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(0) - end - - it 'should return an empty array if milestone does not exist' do - get api("#{base_url}/issues?milestone=foo", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(0) - end - - it 'should return an array of issues in given milestone' do - get api("#{base_url}/issues?milestone=#{title}", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(2) - expect(json_response.first['id']).to eq(issue.id) - expect(json_response.second['id']).to eq(closed_issue.id) - end - - it 'should return an array of issues matching state in milestone' do - get api("#{base_url}/issues?milestone=#{milestone.title}"\ - '&state=closed', user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['id']).to eq(closed_issue.id) - end - end - - describe "GET /projects/:id/issues/:issue_id" do - it "should return a project issue by id" do - get api("/projects/#{project.id}/issues/#{issue.id}", user) - expect(response.status).to eq(200) - expect(json_response['title']).to eq(issue.title) - expect(json_response['iid']).to eq(issue.iid) - end - - it "should return 404 if issue id not found" do - get api("/projects/#{project.id}/issues/54321", user) - expect(response.status).to eq(404) - end - end - - describe "POST /projects/:id/issues" do - it "should create a new project issue" do - post api("/projects/#{project.id}/issues", user), - title: 'new issue', labels: 'label, label2' - expect(response.status).to eq(201) - expect(json_response['title']).to eq('new issue') - expect(json_response['description']).to be_nil - expect(json_response['labels']).to eq(['label', 'label2']) - end - - it "should return a 400 bad request if title not given" do - post api("/projects/#{project.id}/issues", user), labels: 'label, label2' - expect(response.status).to eq(400) - end - - it 'should return 400 on invalid label names' do - post api("/projects/#{project.id}/issues", user), - title: 'new issue', - labels: 'label, ?' - expect(response.status).to eq(400) - expect(json_response['message']['labels']['?']['title']).to eq(['is invalid']) - end - - it 'should return 400 if title is too long' do - post api("/projects/#{project.id}/issues", user), - title: 'g' * 256 - expect(response.status).to eq(400) - expect(json_response['message']['title']).to eq([ - 'is too long (maximum is 255 characters)' - ]) - end - end - - describe "PUT /projects/:id/issues/:issue_id to update only title" do - it "should update a project issue" do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - title: 'updated title' - expect(response.status).to eq(200) - - expect(json_response['title']).to eq('updated title') - end - - it "should return 404 error if issue id not found" do - put api("/projects/#{project.id}/issues/44444", user), - title: 'updated title' - expect(response.status).to eq(404) - end - - it 'should return 400 on invalid label names' do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - title: 'updated title', - labels: 'label, ?' - expect(response.status).to eq(400) - expect(json_response['message']['labels']['?']['title']).to eq(['is invalid']) - end - end - - describe 'PUT /projects/:id/issues/:issue_id to update labels' do - let!(:label) { create(:label, title: 'dummy', project: project) } - let!(:label_link) { create(:label_link, label: label, target: issue) } - - it 'should not update labels if not present' do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - title: 'updated title' - expect(response.status).to eq(200) - expect(json_response['labels']).to eq([label.title]) - end - - it 'should remove all labels' do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - labels: '' - expect(response.status).to eq(200) - expect(json_response['labels']).to eq([]) - end - - it 'should update labels' do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - labels: 'foo,bar' - expect(response.status).to eq(200) - expect(json_response['labels']).to include 'foo' - expect(json_response['labels']).to include 'bar' - end - - it 'should return 400 on invalid label names' do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - labels: 'label, ?' - expect(response.status).to eq(400) - expect(json_response['message']['labels']['?']['title']).to eq(['is invalid']) - end - - it 'should allow special label names' do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - labels: 'label:foo, label-bar,label_bar,label/bar' - expect(response.status).to eq(200) - expect(json_response['labels']).to include 'label:foo' - expect(json_response['labels']).to include 'label-bar' - expect(json_response['labels']).to include 'label_bar' - expect(json_response['labels']).to include 'label/bar' - end - - it 'should return 400 if title is too long' do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - title: 'g' * 256 - expect(response.status).to eq(400) - expect(json_response['message']['title']).to eq([ - 'is too long (maximum is 255 characters)' - ]) - end - end - - describe "PUT /projects/:id/issues/:issue_id to update state and label" do - it "should update a project issue" do - put api("/projects/#{project.id}/issues/#{issue.id}", user), - labels: 'label2', state_event: "close" - expect(response.status).to eq(200) - - expect(json_response['labels']).to include 'label2' - expect(json_response['state']).to eq "closed" - end - end - - describe "DELETE /projects/:id/issues/:issue_id" do - it "should delete a project issue" do - delete api("/projects/#{project.id}/issues/#{issue.id}", user) - expect(response.status).to eq(405) - end - end -end diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb deleted file mode 100644 index aff109a942469fe8d37b61ec2ed8a5a2ed0034b9..0000000000000000000000000000000000000000 --- a/spec/requests/api/labels_spec.rb +++ /dev/null @@ -1,170 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - - let(:user) { create(:user) } - let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) } - let!(:label1) { create(:label, title: 'label1', project: project) } - - before do - project.team << [user, :master] - end - - - describe 'GET /projects/:id/labels' do - it 'should return project labels' do - get api("/projects/#{project.id}/labels", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.size).to eq(1) - expect(json_response.first['name']).to eq(label1.name) - end - end - - describe 'POST /projects/:id/labels' do - it 'should return created label' do - post api("/projects/#{project.id}/labels", user), - name: 'Foo', - color: '#FFAABB' - expect(response.status).to eq(201) - expect(json_response['name']).to eq('Foo') - expect(json_response['color']).to eq('#FFAABB') - end - - it 'should return a 400 bad request if name not given' do - post api("/projects/#{project.id}/labels", user), color: '#FFAABB' - expect(response.status).to eq(400) - end - - it 'should return a 400 bad request if color not given' do - post api("/projects/#{project.id}/labels", user), name: 'Foobar' - expect(response.status).to eq(400) - end - - it 'should return 400 for invalid color' do - post api("/projects/#{project.id}/labels", user), - name: 'Foo', - color: '#FFAA' - expect(response.status).to eq(400) - expect(json_response['message']['color']).to eq(['is invalid']) - end - - it 'should return 400 for too long color code' do - post api("/projects/#{project.id}/labels", user), - name: 'Foo', - color: '#FFAAFFFF' - expect(response.status).to eq(400) - expect(json_response['message']['color']).to eq(['is invalid']) - end - - it 'should return 400 for invalid name' do - post api("/projects/#{project.id}/labels", user), - name: '?', - color: '#FFAABB' - expect(response.status).to eq(400) - expect(json_response['message']['title']).to eq(['is invalid']) - end - - it 'should return 409 if label already exists' do - post api("/projects/#{project.id}/labels", user), - name: 'label1', - color: '#FFAABB' - expect(response.status).to eq(409) - expect(json_response['message']).to eq('Label already exists') - end - end - - describe 'DELETE /projects/:id/labels' do - it 'should return 200 for existing label' do - delete api("/projects/#{project.id}/labels", user), name: 'label1' - expect(response.status).to eq(200) - end - - it 'should return 404 for non existing label' do - delete api("/projects/#{project.id}/labels", user), name: 'label2' - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Label Not Found') - end - - it 'should return 400 for wrong parameters' do - delete api("/projects/#{project.id}/labels", user) - expect(response.status).to eq(400) - end - end - - describe 'PUT /projects/:id/labels' do - it 'should return 200 if name and colors are changed' do - put api("/projects/#{project.id}/labels", user), - name: 'label1', - new_name: 'New Label', - color: '#FFFFFF' - expect(response.status).to eq(200) - expect(json_response['name']).to eq('New Label') - expect(json_response['color']).to eq('#FFFFFF') - end - - it 'should return 200 if name is changed' do - put api("/projects/#{project.id}/labels", user), - name: 'label1', - new_name: 'New Label' - expect(response.status).to eq(200) - expect(json_response['name']).to eq('New Label') - expect(json_response['color']).to eq(label1.color) - end - - it 'should return 200 if colors is changed' do - put api("/projects/#{project.id}/labels", user), - name: 'label1', - color: '#FFFFFF' - expect(response.status).to eq(200) - expect(json_response['name']).to eq(label1.name) - expect(json_response['color']).to eq('#FFFFFF') - end - - it 'should return 404 if label does not exist' do - put api("/projects/#{project.id}/labels", user), - name: 'label2', - new_name: 'label3' - expect(response.status).to eq(404) - end - - it 'should return 400 if no label name given' do - put api("/projects/#{project.id}/labels", user), new_name: 'label2' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('400 (Bad request) "name" not given') - end - - it 'should return 400 if no new parameters given' do - put api("/projects/#{project.id}/labels", user), name: 'label1' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('Required parameters '\ - '"new_name" or "color" missing') - end - - it 'should return 400 for invalid name' do - put api("/projects/#{project.id}/labels", user), - name: 'label1', - new_name: '?', - color: '#FFFFFF' - expect(response.status).to eq(400) - expect(json_response['message']['title']).to eq(['is invalid']) - end - - it 'should return 400 for invalid name' do - put api("/projects/#{project.id}/labels", user), - name: 'label1', - color: '#FF' - expect(response.status).to eq(400) - expect(json_response['message']['color']).to eq(['is invalid']) - end - - it 'should return 400 for too long color code' do - post api("/projects/#{project.id}/labels", user), - name: 'Foo', - color: '#FFAAFFFF' - expect(response.status).to eq(400) - expect(json_response['message']['color']).to eq(['is invalid']) - end - end -end diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb deleted file mode 100644 index 9e252441a4f417d4aeeeb280161fac89f2cf0e08..0000000000000000000000000000000000000000 --- a/spec/requests/api/merge_requests_spec.rb +++ /dev/null @@ -1,409 +0,0 @@ -require "spec_helper" - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let!(:project) {create(:project, creator_id: user.id, namespace: user.namespace) } - let!(:merge_request) { create(:merge_request, :simple, author: user, assignee: user, source_project: project, target_project: project, title: "Test") } - let!(:merge_request_closed) { create(:merge_request, state: "closed", author: user, assignee: user, source_project: project, target_project: project, title: "Closed test") } - let!(:merge_request_merged) { create(:merge_request, state: "merged", author: user, assignee: user, source_project: project, target_project: project, title: "Merged test") } - let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") } - before { - project.team << [user, :reporters] - } - - describe "GET /projects/:id/merge_requests" do - context "when unauthenticated" do - it "should return authentication error" do - get api("/projects/#{project.id}/merge_requests") - expect(response.status).to eq(401) - end - end - - context "when authenticated" do - it "should return an array of all merge_requests" do - get api("/projects/#{project.id}/merge_requests", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(3) - expect(json_response.last['title']).to eq(merge_request.title) - end - - it "should return an array of all merge_requests" do - get api("/projects/#{project.id}/merge_requests?state", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(3) - expect(json_response.last['title']).to eq(merge_request.title) - end - - it "should return an array of open merge_requests" do - get api("/projects/#{project.id}/merge_requests?state=opened", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.last['title']).to eq(merge_request.title) - end - - it "should return an array of closed merge_requests" do - get api("/projects/#{project.id}/merge_requests?state=closed", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(2) - expect(json_response.second['title']).to eq(merge_request_closed.title) - expect(json_response.first['title']).to eq(merge_request_merged.title) - end - - it "should return an array of merged merge_requests" do - get api("/projects/#{project.id}/merge_requests?state=merged", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['title']).to eq(merge_request_merged.title) - end - - context "with ordering" do - before do - @mr_later = mr_with_later_created_and_updated_at_time - @mr_earlier = mr_with_earlier_created_and_updated_at_time - end - - it "should return an array of merge_requests in ascending order" do - get api("/projects/#{project.id}/merge_requests?sort=asc", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(3) - expect(json_response.last['id']).to eq(@mr_earlier.id) - expect(json_response.first['id']).to eq(@mr_later.id) - end - - it "should return an array of merge_requests in descending order" do - get api("/projects/#{project.id}/merge_requests?sort=desc", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(3) - expect(json_response.first['id']).to eq(@mr_later.id) - expect(json_response.last['id']).to eq(@mr_earlier.id) - end - - it "should return an array of merge_requests ordered by updated_at" do - get api("/projects/#{project.id}/merge_requests?order_by=updated_at", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(3) - expect(json_response.last['id']).to eq(@mr_earlier.id) - expect(json_response.first['id']).to eq(@mr_later.id) - end - - it "should return an array of merge_requests ordered by created_at" do - get api("/projects/#{project.id}/merge_requests?sort=created_at", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(3) - expect(json_response.last['id']).to eq(@mr_earlier.id) - expect(json_response.first['id']).to eq(@mr_later.id) - end - end - end - end - - describe "GET /projects/:id/merge_request/:merge_request_id" do - it "should return merge_request" do - get api("/projects/#{project.id}/merge_request/#{merge_request.id}", user) - expect(response.status).to eq(200) - expect(json_response['title']).to eq(merge_request.title) - expect(json_response['iid']).to eq(merge_request.iid) - end - - it "should return a 404 error if merge_request_id not found" do - get api("/projects/#{project.id}/merge_request/999", user) - expect(response.status).to eq(404) - end - end - - describe 'GET /projects/:id/merge_request/:merge_request_id/changes' do - it 'should return the change information of the merge_request' do - get api("/projects/#{project.id}/merge_request/#{merge_request.id}/changes", user) - expect(response.status).to eq 200 - expect(json_response['changes'].size).to eq(merge_request.diffs.size) - end - - it 'returns a 404 when merge_request_id not found' do - get api("/projects/#{project.id}/merge_request/999/changes", user) - expect(response.status).to eq(404) - end - end - - describe "POST /projects/:id/merge_requests" do - context 'between branches projects' do - it "should return merge_request" do - post api("/projects/#{project.id}/merge_requests", user), - title: 'Test merge_request', - source_branch: 'stable', - target_branch: 'master', - author: user, - labels: 'label, label2' - expect(response.status).to eq(201) - expect(json_response['title']).to eq('Test merge_request') - expect(json_response['labels']).to eq(['label', 'label2']) - end - - it "should return 422 when source_branch equals target_branch" do - post api("/projects/#{project.id}/merge_requests", user), - title: "Test merge_request", source_branch: "master", target_branch: "master", author: user - expect(response.status).to eq(422) - end - - it "should return 400 when source_branch is missing" do - post api("/projects/#{project.id}/merge_requests", user), - title: "Test merge_request", target_branch: "master", author: user - expect(response.status).to eq(400) - end - - it "should return 400 when target_branch is missing" do - post api("/projects/#{project.id}/merge_requests", user), - title: "Test merge_request", source_branch: "stable", author: user - expect(response.status).to eq(400) - end - - it "should return 400 when title is missing" do - post api("/projects/#{project.id}/merge_requests", user), - target_branch: 'master', source_branch: 'stable' - expect(response.status).to eq(400) - end - - it 'should return 400 on invalid label names' do - post api("/projects/#{project.id}/merge_requests", user), - title: 'Test merge_request', - source_branch: 'stable', - target_branch: 'master', - author: user, - labels: 'label, ?' - expect(response.status).to eq(400) - expect(json_response['message']['labels']['?']['title']).to eq( - ['is invalid'] - ) - end - - context 'with existing MR' do - before do - post api("/projects/#{project.id}/merge_requests", user), - title: 'Test merge_request', - source_branch: 'stable', - target_branch: 'master', - author: user - @mr = MergeRequest.all.last - end - - it 'should return 409 when MR already exists for source/target' do - expect do - post api("/projects/#{project.id}/merge_requests", user), - title: 'New test merge_request', - source_branch: 'stable', - target_branch: 'master', - author: user - end.to change { MergeRequest.count }.by(0) - expect(response.status).to eq(409) - end - end - end - - context 'forked projects' do - let!(:user2) { create(:user) } - let!(:fork_project) { create(:project, forked_from_project: project, namespace: user2.namespace, creator_id: user2.id) } - let!(:unrelated_project) { create(:project, namespace: create(:user).namespace, creator_id: user2.id) } - - before :each do |each| - fork_project.team << [user2, :reporters] - end - - it "should return merge_request" do - post api("/projects/#{fork_project.id}/merge_requests", user2), - title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user2, target_project_id: project.id, description: 'Test description for Test merge_request' - expect(response.status).to eq(201) - expect(json_response['title']).to eq('Test merge_request') - expect(json_response['description']).to eq('Test description for Test merge_request') - end - - it "should not return 422 when source_branch equals target_branch" do - expect(project.id).not_to eq(fork_project.id) - expect(fork_project.forked?).to be_truthy - expect(fork_project.forked_from_project).to eq(project) - post api("/projects/#{fork_project.id}/merge_requests", user2), - title: 'Test merge_request', source_branch: "master", target_branch: "master", author: user2, target_project_id: project.id - expect(response.status).to eq(201) - expect(json_response['title']).to eq('Test merge_request') - end - - it "should return 400 when source_branch is missing" do - post api("/projects/#{fork_project.id}/merge_requests", user2), - title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id - expect(response.status).to eq(400) - end - - it "should return 400 when target_branch is missing" do - post api("/projects/#{fork_project.id}/merge_requests", user2), - title: 'Test merge_request', target_branch: "master", author: user2, target_project_id: project.id - expect(response.status).to eq(400) - end - - it "should return 400 when title is missing" do - post api("/projects/#{fork_project.id}/merge_requests", user2), - target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: project.id - expect(response.status).to eq(400) - end - - context 'when target_branch is specified' do - it 'should return 422 if not a forked project' do - post api("/projects/#{project.id}/merge_requests", user), - title: 'Test merge_request', - target_branch: 'master', - source_branch: 'stable', - author: user, - target_project_id: fork_project.id - expect(response.status).to eq(422) - end - - it 'should return 422 if targeting a different fork' do - post api("/projects/#{fork_project.id}/merge_requests", user2), - title: 'Test merge_request', - target_branch: 'master', - source_branch: 'stable', - author: user2, - target_project_id: unrelated_project.id - expect(response.status).to eq(422) - end - end - - it "should return 201 when target_branch is specified and for the same project" do - post api("/projects/#{fork_project.id}/merge_requests", user2), - title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: fork_project.id - expect(response.status).to eq(201) - end - end - end - - describe "PUT /projects/:id/merge_request/:merge_request_id to close MR" do - it "should return merge_request" do - put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), state_event: "close" - expect(response.status).to eq(200) - expect(json_response['state']).to eq('closed') - end - end - - describe "PUT /projects/:id/merge_request/:merge_request_id/merge" do - it "should return merge_request in case of success" do - MergeRequest.any_instance.stub(can_be_merged?: true, automerge!: true) - put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) - expect(response.status).to eq(200) - end - - it "should return 405 if branch can't be merged" do - MergeRequest.any_instance.stub(can_be_merged?: false) - put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) - expect(response.status).to eq(405) - expect(json_response['message']).to eq('Branch cannot be merged') - end - - it "should return 405 if merge_request is not open" do - merge_request.close - put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) - expect(response.status).to eq(405) - expect(json_response['message']).to eq('405 Method Not Allowed') - end - - it "should return 401 if user has no permissions to merge" do - user2 = create(:user) - project.team << [user2, :reporter] - put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user2) - expect(response.status).to eq(401) - expect(json_response['message']).to eq('401 Unauthorized') - end - end - - describe "PUT /projects/:id/merge_request/:merge_request_id" do - it "should return merge_request" do - put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), title: "New title" - expect(response.status).to eq(200) - expect(json_response['title']).to eq('New title') - end - - it "should return merge_request" do - put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), description: "New description" - expect(response.status).to eq(200) - expect(json_response['description']).to eq('New description') - end - - it "should return 422 when source_branch and target_branch are renamed the same" do - put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), - source_branch: "master", target_branch: "master" - expect(response.status).to eq(422) - end - - it "should return merge_request with renamed target_branch" do - put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), target_branch: "wiki" - expect(response.status).to eq(200) - expect(json_response['target_branch']).to eq('wiki') - end - - it 'should return 400 on invalid label names' do - put api("/projects/#{project.id}/merge_request/#{merge_request.id}", - user), - title: 'new issue', - labels: 'label, ?' - expect(response.status).to eq(400) - expect(json_response['message']['labels']['?']['title']).to eq(['is invalid']) - end - end - - describe "POST /projects/:id/merge_request/:merge_request_id/comments" do - it "should return comment" do - post api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user), note: "My comment" - expect(response.status).to eq(201) - expect(json_response['note']).to eq('My comment') - end - - it "should return 400 if note is missing" do - post api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user) - expect(response.status).to eq(400) - end - - it "should return 404 if note is attached to non existent merge request" do - post api("/projects/#{project.id}/merge_request/404/comments", user), - note: 'My comment' - expect(response.status).to eq(404) - end - end - - describe "GET :id/merge_request/:merge_request_id/comments" do - it "should return merge_request comments" do - get api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - expect(json_response.first['note']).to eq("a comment on a MR") - expect(json_response.first['author']['id']).to eq(user.id) - end - - it "should return a 404 error if merge_request_id not found" do - get api("/projects/#{project.id}/merge_request/999/comments", user) - expect(response.status).to eq(404) - end - end - - def mr_with_later_created_and_updated_at_time - merge_request - merge_request.created_at += 1.hour - merge_request.updated_at += 30.minutes - merge_request.save - merge_request - end - - def mr_with_earlier_created_and_updated_at_time - merge_request_closed - merge_request_closed.created_at -= 1.hour - merge_request_closed.updated_at -= 30.minutes - merge_request_closed.save - merge_request_closed - end -end diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb deleted file mode 100644 index effb0723476e843bc0e66101baf7e78480bf5b2e..0000000000000000000000000000000000000000 --- a/spec/requests/api/milestones_spec.rb +++ /dev/null @@ -1,116 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let!(:project) { create(:project, namespace: user.namespace ) } - let!(:milestone) { create(:milestone, project: project) } - - before { project.team << [user, :developer] } - - describe 'GET /projects/:id/milestones' do - it 'should return project milestones' do - get api("/projects/#{project.id}/milestones", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['title']).to eq(milestone.title) - end - - it 'should return a 401 error if user not authenticated' do - get api("/projects/#{project.id}/milestones") - expect(response.status).to eq(401) - end - end - - describe 'GET /projects/:id/milestones/:milestone_id' do - it 'should return a project milestone by id' do - get api("/projects/#{project.id}/milestones/#{milestone.id}", user) - expect(response.status).to eq(200) - expect(json_response['title']).to eq(milestone.title) - expect(json_response['iid']).to eq(milestone.iid) - end - - it 'should return 401 error if user not authenticated' do - get api("/projects/#{project.id}/milestones/#{milestone.id}") - expect(response.status).to eq(401) - end - - it 'should return a 404 error if milestone id not found' do - get api("/projects/#{project.id}/milestones/1234", user) - expect(response.status).to eq(404) - end - end - - describe 'POST /projects/:id/milestones' do - it 'should create a new project milestone' do - post api("/projects/#{project.id}/milestones", user), title: 'new milestone' - expect(response.status).to eq(201) - expect(json_response['title']).to eq('new milestone') - expect(json_response['description']).to be_nil - end - - it 'should create a new project milestone with description and due date' do - post api("/projects/#{project.id}/milestones", user), - title: 'new milestone', description: 'release', due_date: '2013-03-02' - expect(response.status).to eq(201) - expect(json_response['description']).to eq('release') - expect(json_response['due_date']).to eq('2013-03-02') - end - - it 'should return a 400 error if title is missing' do - post api("/projects/#{project.id}/milestones", user) - expect(response.status).to eq(400) - end - end - - describe 'PUT /projects/:id/milestones/:milestone_id' do - it 'should update a project milestone' do - put api("/projects/#{project.id}/milestones/#{milestone.id}", user), - title: 'updated title' - expect(response.status).to eq(200) - expect(json_response['title']).to eq('updated title') - end - - it 'should return a 404 error if milestone id not found' do - put api("/projects/#{project.id}/milestones/1234", user), - title: 'updated title' - expect(response.status).to eq(404) - end - end - - describe 'PUT /projects/:id/milestones/:milestone_id to close milestone' do - it 'should update a project milestone' do - put api("/projects/#{project.id}/milestones/#{milestone.id}", user), - state_event: 'close' - expect(response.status).to eq(200) - - expect(json_response['state']).to eq('closed') - end - end - - describe 'PUT /projects/:id/milestones/:milestone_id to test observer on close' do - it 'should create an activity event when an milestone is closed' do - expect(Event).to receive(:create) - - put api("/projects/#{project.id}/milestones/#{milestone.id}", user), - state_event: 'close' - end - end - - describe 'GET /projects/:id/milestones/:milestone_id/issues' do - before do - milestone.issues << create(:issue) - end - it 'should return project issues for a particular milestone' do - get api("/projects/#{project.id}/milestones/#{milestone.id}/issues", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['milestone']['title']).to eq(milestone.title) - end - - it 'should return a 401 error if user not authenticated' do - get api("/projects/#{project.id}/milestones/#{milestone.id}/issues") - expect(response.status).to eq(401) - end - end -end diff --git a/spec/requests/api/namespaces_spec.rb b/spec/requests/api/namespaces_spec.rb deleted file mode 100644 index 6ddaaa0a6dde9603476184e91a9b5814ccd0b34f..0000000000000000000000000000000000000000 --- a/spec/requests/api/namespaces_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - let(:admin) { create(:admin) } - let!(:group1) { create(:group) } - let!(:group2) { create(:group) } - - describe "GET /namespaces" do - context "when unauthenticated" do - it "should return authentication error" do - get api("/namespaces") - expect(response.status).to eq(401) - end - end - - context "when authenticated as admin" do - it "admin: should return an array of all namespaces" do - get api("/namespaces", admin) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - - expect(json_response.length).to eq(Namespace.count) - end - end - end -end diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb deleted file mode 100644 index 8b177af4689b09b63ff434c891d7d4feebdfa358..0000000000000000000000000000000000000000 --- a/spec/requests/api/notes_spec.rb +++ /dev/null @@ -1,188 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let!(:project) { create(:project, namespace: user.namespace ) } - let!(:issue) { create(:issue, project: project, author: user) } - let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: user) } - let!(:snippet) { create(:project_snippet, project: project, author: user) } - let!(:issue_note) { create(:note, noteable: issue, project: project, author: user) } - let!(:merge_request_note) { create(:note, noteable: merge_request, project: project, author: user) } - let!(:snippet_note) { create(:note, noteable: snippet, project: project, author: user) } - before { project.team << [user, :reporter] } - - describe "GET /projects/:id/noteable/:noteable_id/notes" do - context "when noteable is an Issue" do - it "should return an array of issue notes" do - get api("/projects/#{project.id}/issues/#{issue.id}/notes", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['body']).to eq(issue_note.note) - end - - it "should return a 404 error when issue id not found" do - get api("/projects/#{project.id}/issues/123/notes", user) - expect(response.status).to eq(404) - end - end - - context "when noteable is a Snippet" do - it "should return an array of snippet notes" do - get api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['body']).to eq(snippet_note.note) - end - - it "should return a 404 error when snippet id not found" do - get api("/projects/#{project.id}/snippets/42/notes", user) - expect(response.status).to eq(404) - end - end - - context "when noteable is a Merge Request" do - it "should return an array of merge_requests notes" do - get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/notes", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['body']).to eq(merge_request_note.note) - end - - it "should return a 404 error if merge request id not found" do - get api("/projects/#{project.id}/merge_requests/4444/notes", user) - expect(response.status).to eq(404) - end - end - end - - describe "GET /projects/:id/noteable/:noteable_id/notes/:note_id" do - context "when noteable is an Issue" do - it "should return an issue note by id" do - get api("/projects/#{project.id}/issues/#{issue.id}/notes/#{issue_note.id}", user) - expect(response.status).to eq(200) - expect(json_response['body']).to eq(issue_note.note) - end - - it "should return a 404 error if issue note not found" do - get api("/projects/#{project.id}/issues/#{issue.id}/notes/123", user) - expect(response.status).to eq(404) - end - end - - context "when noteable is a Snippet" do - it "should return a snippet note by id" do - get api("/projects/#{project.id}/snippets/#{snippet.id}/notes/#{snippet_note.id}", user) - expect(response.status).to eq(200) - expect(json_response['body']).to eq(snippet_note.note) - end - - it "should return a 404 error if snippet note not found" do - get api("/projects/#{project.id}/snippets/#{snippet.id}/notes/123", user) - expect(response.status).to eq(404) - end - end - end - - describe "POST /projects/:id/noteable/:noteable_id/notes" do - context "when noteable is an Issue" do - it "should create a new issue note" do - post api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!' - expect(response.status).to eq(201) - expect(json_response['body']).to eq('hi!') - expect(json_response['author']['username']).to eq(user.username) - end - - it "should return a 400 bad request error if body not given" do - post api("/projects/#{project.id}/issues/#{issue.id}/notes", user) - expect(response.status).to eq(400) - end - - it "should return a 401 unauthorized error if user not authenticated" do - post api("/projects/#{project.id}/issues/#{issue.id}/notes"), body: 'hi!' - expect(response.status).to eq(401) - end - end - - context "when noteable is a Snippet" do - it "should create a new snippet note" do - post api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user), body: 'hi!' - expect(response.status).to eq(201) - expect(json_response['body']).to eq('hi!') - expect(json_response['author']['username']).to eq(user.username) - end - - it "should return a 400 bad request error if body not given" do - post api("/projects/#{project.id}/snippets/#{snippet.id}/notes", user) - expect(response.status).to eq(400) - end - - it "should return a 401 unauthorized error if user not authenticated" do - post api("/projects/#{project.id}/snippets/#{snippet.id}/notes"), body: 'hi!' - expect(response.status).to eq(401) - end - end - end - - describe "POST /projects/:id/noteable/:noteable_id/notes to test observer on create" do - it "should create an activity event when an issue note is created" do - expect(Event).to receive(:create) - - post api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!' - end - end - - describe 'PUT /projects/:id/noteable/:noteable_id/notes/:note_id' do - context 'when noteable is an Issue' do - it 'should return modified note' do - put api("/projects/#{project.id}/issues/#{issue.id}/"\ - "notes/#{issue_note.id}", user), body: 'Hello!' - expect(response.status).to eq(200) - expect(json_response['body']).to eq('Hello!') - end - - it 'should return a 404 error when note id not found' do - put api("/projects/#{project.id}/issues/#{issue.id}/notes/123", user), - body: 'Hello!' - expect(response.status).to eq(404) - end - - it 'should return a 400 bad request error if body not given' do - put api("/projects/#{project.id}/issues/#{issue.id}/"\ - "notes/#{issue_note.id}", user) - expect(response.status).to eq(400) - end - end - - context 'when noteable is a Snippet' do - it 'should return modified note' do - put api("/projects/#{project.id}/snippets/#{snippet.id}/"\ - "notes/#{snippet_note.id}", user), body: 'Hello!' - expect(response.status).to eq(200) - expect(json_response['body']).to eq('Hello!') - end - - it 'should return a 404 error when note id not found' do - put api("/projects/#{project.id}/snippets/#{snippet.id}/"\ - "notes/123", user), body: "Hello!" - expect(response.status).to eq(404) - end - end - - context 'when noteable is a Merge Request' do - it 'should return modified note' do - put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\ - "notes/#{merge_request_note.id}", user), body: 'Hello!' - expect(response.status).to eq(200) - expect(json_response['body']).to eq('Hello!') - end - - it 'should return a 404 error when note id not found' do - put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/"\ - "notes/123", user), body: "Hello!" - expect(response.status).to eq(404) - end - end - end - -end diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb deleted file mode 100644 index 81fe68de662c94a01a4d8090da89a50268262178..0000000000000000000000000000000000000000 --- a/spec/requests/api/project_hooks_spec.rb +++ /dev/null @@ -1,129 +0,0 @@ -require 'spec_helper' - -describe API::API, 'ProjectHooks', api: true do - include ApiHelpers - let(:user) { create(:user) } - let(:user3) { create(:user) } - let!(:project) { create(:project, creator_id: user.id, namespace: user.namespace) } - let!(:hook) { create(:project_hook, project: project, url: "http://example.com") } - - before do - project.team << [user, :master] - project.team << [user3, :developer] - end - - describe "GET /projects/:id/hooks" do - context "authorized user" do - it "should return project hooks" do - get api("/projects/#{project.id}/hooks", user) - expect(response.status).to eq(200) - - expect(json_response).to be_an Array - expect(json_response.count).to eq(1) - expect(json_response.first['url']).to eq("http://example.com") - end - end - - context "unauthorized user" do - it "should not access project hooks" do - get api("/projects/#{project.id}/hooks", user3) - expect(response.status).to eq(403) - end - end - end - - describe "GET /projects/:id/hooks/:hook_id" do - context "authorized user" do - it "should return a project hook" do - get api("/projects/#{project.id}/hooks/#{hook.id}", user) - expect(response.status).to eq(200) - expect(json_response['url']).to eq(hook.url) - end - - it "should return a 404 error if hook id is not available" do - get api("/projects/#{project.id}/hooks/1234", user) - expect(response.status).to eq(404) - end - end - - context "unauthorized user" do - it "should not access an existing hook" do - get api("/projects/#{project.id}/hooks/#{hook.id}", user3) - expect(response.status).to eq(403) - end - end - - it "should return a 404 error if hook id is not available" do - get api("/projects/#{project.id}/hooks/1234", user) - expect(response.status).to eq(404) - end - end - - describe "POST /projects/:id/hooks" do - it "should add hook to project" do - expect { - post api("/projects/#{project.id}/hooks", user), - url: "http://example.com", issues_events: true - }.to change {project.hooks.count}.by(1) - expect(response.status).to eq(201) - end - - it "should return a 400 error if url not given" do - post api("/projects/#{project.id}/hooks", user) - expect(response.status).to eq(400) - end - - it "should return a 422 error if url not valid" do - post api("/projects/#{project.id}/hooks", user), "url" => "ftp://example.com" - expect(response.status).to eq(422) - end - end - - describe "PUT /projects/:id/hooks/:hook_id" do - it "should update an existing project hook" do - put api("/projects/#{project.id}/hooks/#{hook.id}", user), - url: 'http://example.org', push_events: false - expect(response.status).to eq(200) - expect(json_response['url']).to eq('http://example.org') - end - - it "should return 404 error if hook id not found" do - put api("/projects/#{project.id}/hooks/1234", user), url: 'http://example.org' - expect(response.status).to eq(404) - end - - it "should return 400 error if url is not given" do - put api("/projects/#{project.id}/hooks/#{hook.id}", user) - expect(response.status).to eq(400) - end - - it "should return a 422 error if url is not valid" do - put api("/projects/#{project.id}/hooks/#{hook.id}", user), url: 'ftp://example.com' - expect(response.status).to eq(422) - end - end - - describe "DELETE /projects/:id/hooks/:hook_id" do - it "should delete hook from project" do - expect { - delete api("/projects/#{project.id}/hooks/#{hook.id}", user) - }.to change {project.hooks.count}.by(-1) - expect(response.status).to eq(200) - end - - it "should return success when deleting hook" do - delete api("/projects/#{project.id}/hooks/#{hook.id}", user) - expect(response.status).to eq(200) - end - - it "should return success when deleting non existent hook" do - delete api("/projects/#{project.id}/hooks/42", user) - expect(response.status).to eq(200) - end - - it "should return a 405 error if hook id not given" do - delete api("/projects/#{project.id}/hooks", user) - expect(response.status).to eq(405) - end - end -end diff --git a/spec/requests/api/project_members_spec.rb b/spec/requests/api/project_members_spec.rb deleted file mode 100644 index 8419a364ed115501b4d512cd73878c5766f0bc40..0000000000000000000000000000000000000000 --- a/spec/requests/api/project_members_spec.rb +++ /dev/null @@ -1,153 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:user3) { create(:user) } - let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) } - let(:project_member) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) } - let(:project_member2) { create(:project_member, user: user3, project: project, access_level: ProjectMember::DEVELOPER) } - - describe "GET /projects/:id/members" do - before { project_member } - before { project_member2 } - - it "should return project team members" do - get api("/projects/#{project.id}/members", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.count).to eq(2) - expect(json_response.map { |u| u['username'] }).to include user.username - end - - it "finds team members with query string" do - get api("/projects/#{project.id}/members", user), query: user.username - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.count).to eq(1) - expect(json_response.first['username']).to eq(user.username) - end - - it "should return a 404 error if id not found" do - get api("/projects/9999/members", user) - expect(response.status).to eq(404) - end - end - - describe "GET /projects/:id/members/:user_id" do - before { project_member } - - it "should return project team member" do - get api("/projects/#{project.id}/members/#{user.id}", user) - expect(response.status).to eq(200) - expect(json_response['username']).to eq(user.username) - expect(json_response['access_level']).to eq(ProjectMember::MASTER) - end - - it "should return a 404 error if user id not found" do - get api("/projects/#{project.id}/members/1234", user) - expect(response.status).to eq(404) - end - end - - describe "POST /projects/:id/members" do - it "should add user to project team" do - expect { - post api("/projects/#{project.id}/members", user), user_id: user2.id, - access_level: ProjectMember::DEVELOPER - }.to change { ProjectMember.count }.by(1) - - expect(response.status).to eq(201) - expect(json_response['username']).to eq(user2.username) - expect(json_response['access_level']).to eq(ProjectMember::DEVELOPER) - end - - it "should return a 201 status if user is already project member" do - post api("/projects/#{project.id}/members", user), user_id: user2.id, - access_level: ProjectMember::DEVELOPER - expect { - post api("/projects/#{project.id}/members", user), user_id: user2.id, - access_level: ProjectMember::DEVELOPER - }.not_to change { ProjectMember.count } - - expect(response.status).to eq(201) - expect(json_response['username']).to eq(user2.username) - expect(json_response['access_level']).to eq(ProjectMember::DEVELOPER) - end - - it "should return a 400 error when user id is not given" do - post api("/projects/#{project.id}/members", user), access_level: ProjectMember::MASTER - expect(response.status).to eq(400) - end - - it "should return a 400 error when access level is not given" do - post api("/projects/#{project.id}/members", user), user_id: user2.id - expect(response.status).to eq(400) - end - - it "should return a 422 error when access level is not known" do - post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234 - expect(response.status).to eq(422) - end - end - - describe "PUT /projects/:id/members/:user_id" do - before { project_member2 } - - it "should update project team member" do - put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: ProjectMember::MASTER - expect(response.status).to eq(200) - expect(json_response['username']).to eq(user3.username) - expect(json_response['access_level']).to eq(ProjectMember::MASTER) - end - - it "should return a 404 error if user_id is not found" do - put api("/projects/#{project.id}/members/1234", user), access_level: ProjectMember::MASTER - expect(response.status).to eq(404) - end - - it "should return a 400 error when access level is not given" do - put api("/projects/#{project.id}/members/#{user3.id}", user) - expect(response.status).to eq(400) - end - - it "should return a 422 error when access level is not known" do - put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: 123 - expect(response.status).to eq(422) - end - end - - describe "DELETE /projects/:id/members/:user_id" do - before { project_member } - before { project_member2 } - - it "should remove user from project team" do - expect { - delete api("/projects/#{project.id}/members/#{user3.id}", user) - }.to change { ProjectMember.count }.by(-1) - end - - it "should return 200 if team member is not part of a project" do - delete api("/projects/#{project.id}/members/#{user3.id}", user) - expect { - delete api("/projects/#{project.id}/members/#{user3.id}", user) - }.to_not change { ProjectMember.count } - end - - it "should return 200 if team member already removed" do - delete api("/projects/#{project.id}/members/#{user3.id}", user) - delete api("/projects/#{project.id}/members/#{user3.id}", user) - expect(response.status).to eq(200) - end - - it "should return 200 OK when the user was not member" do - expect { - delete api("/projects/#{project.id}/members/1000000", user) - }.to change { ProjectMember.count }.by(0) - expect(response.status).to eq(200) - expect(json_response['message']).to eq("Access revoked") - expect(json_response['id']).to eq(1000000) - end - end -end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb deleted file mode 100644 index cc387378d3a824bd464a484b3fb147cf86716ab8..0000000000000000000000000000000000000000 --- a/spec/requests/api/projects_spec.rb +++ /dev/null @@ -1,825 +0,0 @@ -# -*- coding: utf-8 -*- -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - include Gitlab::CurrentSettings - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:user3) { create(:user) } - let(:admin) { create(:admin) } - let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) } - let(:project2) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace) } - let(:project3) { create(:project, path: 'project3', creator_id: user.id, namespace: user.namespace) } - let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') } - let(:project_member) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) } - let(:project_member2) { create(:project_member, user: user3, project: project, access_level: ProjectMember::DEVELOPER) } - let(:user4) { create(:user) } - let(:project3) do - create(:project, - name: 'second_project', - path: 'second_project', - creator_id: user.id, - namespace: user.namespace, - merge_requests_enabled: false, - issues_enabled: false, wiki_enabled: false, - snippets_enabled: false, visibility_level: 0) - end - let(:project_member3) do - create(:project_member, - user: user4, - project: project3, - access_level: ProjectMember::MASTER) - end - let(:project4) do - create(:project, - name: 'third_project', - path: 'third_project', - creator_id: user4.id, - namespace: user4.namespace) - end - - describe 'GET /projects' do - before { project } - - context 'when unauthenticated' do - it 'should return authentication error' do - get api('/projects') - expect(response.status).to eq(401) - end - end - - context 'when authenticated' do - it 'should return an array of projects' do - get api('/projects', user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['name']).to eq(project.name) - expect(json_response.first['owner']['username']).to eq(user.username) - end - - it 'should include the project labels as the tag_list' do - get api('/projects', user) - response.status.should == 200 - json_response.should be_an Array - json_response.first.keys.should include('tag_list') - end - - context 'and using search' do - it 'should return searched project' do - get api('/projects', user), { search: project.name } - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.length).to eq(1) - end - end - - context 'and using sorting' do - before do - project2 - project3 - end - - it 'should return the correct order when sorted by id' do - get api('/projects', user), { order_by: 'id', sort: 'desc'} - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['id']).to eq(project3.id) - end - end - end - end - - describe 'GET /projects/all' do - before { project } - - context 'when unauthenticated' do - it 'should return authentication error' do - get api('/projects/all') - expect(response.status).to eq(401) - end - end - - context 'when authenticated as regular user' do - it 'should return authentication error' do - get api('/projects/all', user) - expect(response.status).to eq(403) - end - end - - context 'when authenticated as admin' do - it 'should return an array of all projects' do - get api('/projects/all', admin) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - project_name = project.name - - expect(json_response.detect { - |project| project['name'] == project_name - }['name']).to eq(project_name) - - expect(json_response.detect { - |project| project['owner']['username'] == user.username - }['owner']['username']).to eq(user.username) - end - end - end - - describe 'POST /projects' do - context 'maximum number of projects reached' do - it 'should not create new project and respond with 403' do - allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0) - expect { - post api('/projects', user2), name: 'foo' - }.to change {Project.count}.by(0) - expect(response.status).to eq(403) - end - end - - it 'should create new project without path and return 201' do - expect { post api('/projects', user), name: 'foo' }. - to change { Project.count }.by(1) - expect(response.status).to eq(201) - end - - it 'should create last project before reaching project limit' do - allow_any_instance_of(User).to receive(:projects_limit_left).and_return(1) - post api('/projects', user2), name: 'foo' - expect(response.status).to eq(201) - end - - it 'should not create new project without name and return 400' do - expect { post api('/projects', user) }.to_not change { Project.count } - expect(response.status).to eq(400) - end - - it "should assign attributes to project" do - project = attributes_for(:project, { - path: 'camelCasePath', - description: Faker::Lorem.sentence, - issues_enabled: false, - merge_requests_enabled: false, - wiki_enabled: false - }) - - post api('/projects', user), project - - project.each_pair do |k,v| - expect(json_response[k.to_s]).to eq(v) - end - end - - it 'should set a project as public' do - project = attributes_for(:project, :public) - post api('/projects', user), project - expect(json_response['public']).to be_truthy - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC) - end - - it 'should set a project as public using :public' do - project = attributes_for(:project, { public: true }) - post api('/projects', user), project - expect(json_response['public']).to be_truthy - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC) - end - - it 'should set a project as internal' do - project = attributes_for(:project, :internal) - post api('/projects', user), project - expect(json_response['public']).to be_falsey - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL) - end - - it 'should set a project as internal overriding :public' do - project = attributes_for(:project, :internal, { public: true }) - post api('/projects', user), project - expect(json_response['public']).to be_falsey - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL) - end - - it 'should set a project as private' do - project = attributes_for(:project, :private) - post api('/projects', user), project - expect(json_response['public']).to be_falsey - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE) - end - - it 'should set a project as private using :public' do - project = attributes_for(:project, { public: false }) - post api('/projects', user), project - expect(json_response['public']).to be_falsey - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE) - end - - context 'when a visibility level is restricted' do - before do - @project = attributes_for(:project, { public: true }) - allow_any_instance_of(ApplicationSetting).to( - receive(:restricted_visibility_levels).and_return([20]) - ) - end - - it 'should not allow a non-admin to use a restricted visibility level' do - post api('/projects', user), @project - expect(response.status).to eq(400) - expect(json_response['message']['visibility_level'].first).to( - match('restricted by your GitLab administrator') - ) - end - - it 'should allow an admin to override restricted visibility settings' do - post api('/projects', admin), @project - expect(json_response['public']).to be_truthy - expect(json_response['visibility_level']).to( - eq(Gitlab::VisibilityLevel::PUBLIC) - ) - end - end - end - - describe 'POST /projects/user/:id' do - before { project } - before { admin } - - it 'should create new project without path and return 201' do - expect { post api("/projects/user/#{user.id}", admin), name: 'foo' }.to change {Project.count}.by(1) - expect(response.status).to eq(201) - end - - it 'should respond with 400 on failure and not project' do - expect { post api("/projects/user/#{user.id}", admin) }. - to_not change { Project.count } - - expect(response.status).to eq(400) - expect(json_response['message']['name']).to eq([ - 'can\'t be blank', - 'is too short (minimum is 0 characters)', - Gitlab::Regex.project_name_regex_message - ]) - expect(json_response['message']['path']).to eq([ - 'can\'t be blank', - 'is too short (minimum is 0 characters)', - Gitlab::Regex.send(:project_path_regex_message) - ]) - end - - it 'should assign attributes to project' do - project = attributes_for(:project, { - description: Faker::Lorem.sentence, - issues_enabled: false, - merge_requests_enabled: false, - wiki_enabled: false - }) - - post api("/projects/user/#{user.id}", admin), project - - project.each_pair do |k,v| - next if k == :path - expect(json_response[k.to_s]).to eq(v) - end - end - - it 'should set a project as public' do - project = attributes_for(:project, :public) - post api("/projects/user/#{user.id}", admin), project - expect(json_response['public']).to be_truthy - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC) - end - - it 'should set a project as public using :public' do - project = attributes_for(:project, { public: true }) - post api("/projects/user/#{user.id}", admin), project - expect(json_response['public']).to be_truthy - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC) - end - - it 'should set a project as internal' do - project = attributes_for(:project, :internal) - post api("/projects/user/#{user.id}", admin), project - expect(json_response['public']).to be_falsey - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL) - end - - it 'should set a project as internal overriding :public' do - project = attributes_for(:project, :internal, { public: true }) - post api("/projects/user/#{user.id}", admin), project - expect(json_response['public']).to be_falsey - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL) - end - - it 'should set a project as private' do - project = attributes_for(:project, :private) - post api("/projects/user/#{user.id}", admin), project - expect(json_response['public']).to be_falsey - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE) - end - - it 'should set a project as private using :public' do - project = attributes_for(:project, { public: false }) - post api("/projects/user/#{user.id}", admin), project - expect(json_response['public']).to be_falsey - expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE) - end - end - - describe 'GET /projects/:id' do - before { project } - before { project_member } - - it 'should return a project by id' do - get api("/projects/#{project.id}", user) - expect(response.status).to eq(200) - expect(json_response['name']).to eq(project.name) - expect(json_response['owner']['username']).to eq(user.username) - end - - it 'should return a project by path name' do - get api("/projects/#{project.id}", user) - expect(response.status).to eq(200) - expect(json_response['name']).to eq(project.name) - end - - it 'should return a 404 error if not found' do - get api('/projects/42', user) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Project Not Found') - end - - it 'should return a 404 error if user is not a member' do - other_user = create(:user) - get api("/projects/#{project.id}", other_user) - expect(response.status).to eq(404) - end - - describe 'permissions' do - context 'personal project' do - it 'Sets project access and returns 200' do - project.team << [user, :master] - get api("/projects/#{project.id}", user) - - expect(response.status).to eq(200) - expect(json_response['permissions']['project_access']['access_level']). - to eq(Gitlab::Access::MASTER) - expect(json_response['permissions']['group_access']).to be_nil - end - end - - context 'group project' do - it 'should set the owner and return 200' do - project2 = create(:project, group: create(:group)) - project2.group.add_owner(user) - get api("/projects/#{project2.id}", user) - - expect(response.status).to eq(200) - expect(json_response['permissions']['project_access']).to be_nil - expect(json_response['permissions']['group_access']['access_level']). - to eq(Gitlab::Access::OWNER) - end - end - end - end - - describe 'GET /projects/:id/events' do - before { project_member2 } - - it 'should return a project events' do - get api("/projects/#{project.id}/events", user) - expect(response.status).to eq(200) - json_event = json_response.first - - expect(json_event['action_name']).to eq('joined') - expect(json_event['project_id'].to_i).to eq(project.id) - expect(json_event['author_username']).to eq(user3.username) - end - - it 'should return a 404 error if not found' do - get api('/projects/42/events', user) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Project Not Found') - end - - it 'should return a 404 error if user is not a member' do - other_user = create(:user) - get api("/projects/#{project.id}/events", other_user) - expect(response.status).to eq(404) - end - end - - describe 'GET /projects/:id/snippets' do - before { snippet } - - it 'should return an array of project snippets' do - get api("/projects/#{project.id}/snippets", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['title']).to eq(snippet.title) - end - end - - describe 'GET /projects/:id/snippets/:snippet_id' do - it 'should return a project snippet' do - get api("/projects/#{project.id}/snippets/#{snippet.id}", user) - expect(response.status).to eq(200) - expect(json_response['title']).to eq(snippet.title) - end - - it 'should return a 404 error if snippet id not found' do - get api("/projects/#{project.id}/snippets/1234", user) - expect(response.status).to eq(404) - end - end - - describe 'POST /projects/:id/snippets' do - it 'should create a new project snippet' do - post api("/projects/#{project.id}/snippets", user), - title: 'api test', file_name: 'sample.rb', code: 'test', - visibility_level: '0' - expect(response.status).to eq(201) - expect(json_response['title']).to eq('api test') - end - - it 'should return a 400 error if invalid snippet is given' do - post api("/projects/#{project.id}/snippets", user) - expect(status).to eq(400) - end - end - - describe 'PUT /projects/:id/snippets/:shippet_id' do - it 'should update an existing project snippet' do - put api("/projects/#{project.id}/snippets/#{snippet.id}", user), - code: 'updated code' - expect(response.status).to eq(200) - expect(json_response['title']).to eq('example') - expect(snippet.reload.content).to eq('updated code') - end - - it 'should update an existing project snippet with new title' do - put api("/projects/#{project.id}/snippets/#{snippet.id}", user), - title: 'other api test' - expect(response.status).to eq(200) - expect(json_response['title']).to eq('other api test') - end - end - - describe 'DELETE /projects/:id/snippets/:snippet_id' do - before { snippet } - - it 'should delete existing project snippet' do - expect { - delete api("/projects/#{project.id}/snippets/#{snippet.id}", user) - }.to change { Snippet.count }.by(-1) - expect(response.status).to eq(200) - end - - it 'should return 404 when deleting unknown snippet id' do - delete api("/projects/#{project.id}/snippets/1234", user) - expect(response.status).to eq(404) - end - end - - describe 'GET /projects/:id/snippets/:snippet_id/raw' do - it 'should get a raw project snippet' do - get api("/projects/#{project.id}/snippets/#{snippet.id}/raw", user) - expect(response.status).to eq(200) - end - - it 'should return a 404 error if raw project snippet not found' do - get api("/projects/#{project.id}/snippets/5555/raw", user) - expect(response.status).to eq(404) - end - end - - describe :deploy_keys do - let(:deploy_keys_project) { create(:deploy_keys_project, project: project) } - let(:deploy_key) { deploy_keys_project.deploy_key } - - describe 'GET /projects/:id/keys' do - before { deploy_key } - - it 'should return array of ssh keys' do - get api("/projects/#{project.id}/keys", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['title']).to eq(deploy_key.title) - end - end - - describe 'GET /projects/:id/keys/:key_id' do - it 'should return a single key' do - get api("/projects/#{project.id}/keys/#{deploy_key.id}", user) - expect(response.status).to eq(200) - expect(json_response['title']).to eq(deploy_key.title) - end - - it 'should return 404 Not Found with invalid ID' do - get api("/projects/#{project.id}/keys/404", user) - expect(response.status).to eq(404) - end - end - - describe 'POST /projects/:id/keys' do - it 'should not create an invalid ssh key' do - post api("/projects/#{project.id}/keys", user), { title: 'invalid key' } - expect(response.status).to eq(400) - expect(json_response['message']['key']).to eq([ - 'can\'t be blank', - 'is too short (minimum is 0 characters)', - 'is invalid' - ]) - end - - it 'should not create a key without title' do - post api("/projects/#{project.id}/keys", user), key: 'some key' - expect(response.status).to eq(400) - expect(json_response['message']['title']).to eq([ - 'can\'t be blank', - 'is too short (minimum is 0 characters)' - ]) - end - - it 'should create new ssh key' do - key_attrs = attributes_for :key - expect { - post api("/projects/#{project.id}/keys", user), key_attrs - }.to change{ project.deploy_keys.count }.by(1) - end - end - - describe 'DELETE /projects/:id/keys/:key_id' do - before { deploy_key } - - it 'should delete existing key' do - expect { - delete api("/projects/#{project.id}/keys/#{deploy_key.id}", user) - }.to change{ project.deploy_keys.count }.by(-1) - end - - it 'should return 404 Not Found with invalid ID' do - delete api("/projects/#{project.id}/keys/404", user) - expect(response.status).to eq(404) - end - end - end - - describe :fork_admin do - let(:project_fork_target) { create(:project) } - let(:project_fork_source) { create(:project, :public) } - - describe 'POST /projects/:id/fork/:forked_from_id' do - let(:new_project_fork_source) { create(:project, :public) } - - it "shouldn't available for non admin users" do - post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user) - expect(response.status).to eq(403) - end - - it 'should allow project to be forked from an existing project' do - expect(project_fork_target.forked?).not_to be_truthy - post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) - expect(response.status).to eq(201) - project_fork_target.reload - expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id) - expect(project_fork_target.forked_project_link).not_to be_nil - expect(project_fork_target.forked?).to be_truthy - end - - it 'should fail if forked_from project which does not exist' do - post api("/projects/#{project_fork_target.id}/fork/9999", admin) - expect(response.status).to eq(404) - end - - it 'should fail with 409 if already forked' do - post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) - project_fork_target.reload - expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id) - post api("/projects/#{project_fork_target.id}/fork/#{new_project_fork_source.id}", admin) - expect(response.status).to eq(409) - project_fork_target.reload - expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id) - expect(project_fork_target.forked?).to be_truthy - end - end - - describe 'DELETE /projects/:id/fork' do - - it "shouldn't available for non admin users" do - delete api("/projects/#{project_fork_target.id}/fork", user) - expect(response.status).to eq(403) - end - - it 'should make forked project unforked' do - post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) - project_fork_target.reload - expect(project_fork_target.forked_from_project).not_to be_nil - expect(project_fork_target.forked?).to be_truthy - delete api("/projects/#{project_fork_target.id}/fork", admin) - expect(response.status).to eq(200) - project_fork_target.reload - expect(project_fork_target.forked_from_project).to be_nil - expect(project_fork_target.forked?).not_to be_truthy - end - - it 'should be idempotent if not forked' do - expect(project_fork_target.forked_from_project).to be_nil - delete api("/projects/#{project_fork_target.id}/fork", admin) - expect(response.status).to eq(200) - expect(project_fork_target.reload.forked_from_project).to be_nil - end - end - end - - describe 'GET /projects/search/:query' do - let!(:query) { 'query'} - let!(:search) { create(:empty_project, name: query, creator_id: user.id, namespace: user.namespace) } - let!(:pre) { create(:empty_project, name: "pre_#{query}", creator_id: user.id, namespace: user.namespace) } - let!(:post) { create(:empty_project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) } - let!(:pre_post) { create(:empty_project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) } - let!(:unfound) { create(:empty_project, name: 'unfound', creator_id: user.id, namespace: user.namespace) } - let!(:internal) { create(:empty_project, :internal, name: "internal #{query}") } - let!(:unfound_internal) { create(:empty_project, :internal, name: 'unfound internal') } - let!(:public) { create(:empty_project, :public, name: "public #{query}") } - let!(:unfound_public) { create(:empty_project, :public, name: 'unfound public') } - - context 'when unauthenticated' do - it 'should return authentication error' do - get api("/projects/search/#{query}") - expect(response.status).to eq(401) - end - end - - context 'when authenticated' do - it 'should return an array of projects' do - get api("/projects/search/#{query}",user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.size).to eq(6) - json_response.each {|project| expect(project['name']).to match(/.*query.*/)} - end - end - - context 'when authenticated as a different user' do - it 'should return matching public projects' do - get api("/projects/search/#{query}", user2) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.size).to eq(2) - json_response.each {|project| expect(project['name']).to match(/(internal|public) query/)} - end - end - end - - describe 'PUT /projects/:id̈́' do - before { project } - before { user } - before { user3 } - before { user4 } - before { project3 } - before { project4 } - before { project_member3 } - before { project_member2 } - - context 'when unauthenticated' do - it 'should return authentication error' do - project_param = { name: 'bar' } - put api("/projects/#{project.id}"), project_param - expect(response.status).to eq(401) - end - end - - context 'when authenticated as project owner' do - it 'should update name' do - project_param = { name: 'bar' } - put api("/projects/#{project.id}", user), project_param - expect(response.status).to eq(200) - project_param.each_pair do |k, v| - expect(json_response[k.to_s]).to eq(v) - end - end - - it 'should update visibility_level' do - project_param = { visibility_level: 20 } - put api("/projects/#{project3.id}", user), project_param - expect(response.status).to eq(200) - project_param.each_pair do |k, v| - expect(json_response[k.to_s]).to eq(v) - end - end - - it 'should not update name to existing name' do - project_param = { name: project3.name } - put api("/projects/#{project.id}", user), project_param - expect(response.status).to eq(400) - expect(json_response['message']['name']).to eq(['has already been taken']) - end - - it 'should update path & name to existing path & name in different namespace' do - project_param = { path: project4.path, name: project4.name } - put api("/projects/#{project3.id}", user), project_param - expect(response.status).to eq(200) - project_param.each_pair do |k, v| - expect(json_response[k.to_s]).to eq(v) - end - end - end - - context 'when authenticated as project master' do - it 'should update path' do - project_param = { path: 'bar' } - put api("/projects/#{project3.id}", user4), project_param - expect(response.status).to eq(200) - project_param.each_pair do |k, v| - expect(json_response[k.to_s]).to eq(v) - end - end - - it 'should update other attributes' do - project_param = { issues_enabled: true, - wiki_enabled: true, - snippets_enabled: true, - merge_requests_enabled: true, - description: 'new description' } - - put api("/projects/#{project3.id}", user4), project_param - expect(response.status).to eq(200) - project_param.each_pair do |k, v| - expect(json_response[k.to_s]).to eq(v) - end - end - - it 'should not update path to existing path' do - project_param = { path: project.path } - put api("/projects/#{project3.id}", user4), project_param - expect(response.status).to eq(400) - expect(json_response['message']['path']).to eq(['has already been taken']) - end - - it 'should not update name' do - project_param = { name: 'bar' } - put api("/projects/#{project3.id}", user4), project_param - expect(response.status).to eq(403) - end - - it 'should not update visibility_level' do - project_param = { visibility_level: 20 } - put api("/projects/#{project3.id}", user4), project_param - expect(response.status).to eq(403) - end - end - - context 'when authenticated as project developer' do - it 'should not update other attributes' do - project_param = { path: 'bar', - issues_enabled: true, - wiki_enabled: true, - snippets_enabled: true, - merge_requests_enabled: true, - description: 'new description' } - put api("/projects/#{project.id}", user3), project_param - expect(response.status).to eq(403) - end - end - end - - describe 'DELETE /projects/:id' do - context 'when authenticated as user' do - it 'should remove project' do - expect(GitlabShellWorker).to( - receive(:perform_async).with(:remove_repository, - /#{project.path_with_namespace}/) - ).twice - - delete api("/projects/#{project.id}", user) - expect(response.status).to eq(200) - end - - it 'should not remove a project if not an owner' do - user3 = create(:user) - project.team << [user3, :developer] - delete api("/projects/#{project.id}", user3) - expect(response.status).to eq(403) - end - - it 'should not remove a non existing project' do - delete api('/projects/1328', user) - expect(response.status).to eq(404) - end - - it 'should not remove a project not attached to user' do - delete api("/projects/#{project.id}", user2) - expect(response.status).to eq(404) - end - end - - context 'when authenticated as admin' do - it 'should remove any existing project' do - delete api("/projects/#{project.id}", admin) - expect(response.status).to eq(200) - end - - it 'should not remove a non existing project' do - delete api('/projects/1328', admin) - expect(response.status).to eq(404) - end - end - end -end diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb deleted file mode 100644 index 09a79553f729cab2d5d53320f474c4ff6fb01b72..0000000000000000000000000000000000000000 --- a/spec/requests/api/repositories_spec.rb +++ /dev/null @@ -1,247 +0,0 @@ -require 'spec_helper' -require 'mime/types' - -describe API::API, api: true do - include ApiHelpers - include RepoHelpers - - let(:user) { create(:user) } - let(:user2) { create(:user) } - let!(:project) { create(:project, creator_id: user.id) } - let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) } - let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) } - - describe "GET /projects/:id/repository/tags" do - it "should return an array of project tags" do - get api("/projects/#{project.id}/repository/tags", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['name']).to eq(project.repo.tags.sort_by(&:name).reverse.first.name) - end - end - - describe 'POST /projects/:id/repository/tags' do - context 'lightweight tags' do - it 'should create a new tag' do - post api("/projects/#{project.id}/repository/tags", user), - tag_name: 'v7.0.1', - ref: 'master' - - expect(response.status).to eq(201) - expect(json_response['name']).to eq('v7.0.1') - end - end - - context 'annotated tag' do - it 'should create a new annotated tag' do - # Identity must be set in .gitconfig to create annotated tag. - repo_path = project.repository.path_to_repo - system(*%W(git --git-dir=#{repo_path} config user.name #{user.name})) - system(*%W(git --git-dir=#{repo_path} config user.email #{user.email})) - - post api("/projects/#{project.id}/repository/tags", user), - tag_name: 'v7.1.0', - ref: 'master', - message: 'Release 7.1.0' - - expect(response.status).to eq(201) - expect(json_response['name']).to eq('v7.1.0') - expect(json_response['message']).to eq('Release 7.1.0') - end - end - - it 'should deny for user without push access' do - post api("/projects/#{project.id}/repository/tags", user2), - tag_name: 'v1.9.0', - ref: '621491c677087aa243f165eab467bfdfbee00be1' - expect(response.status).to eq(403) - end - - it 'should return 400 if tag name is invalid' do - post api("/projects/#{project.id}/repository/tags", user), - tag_name: 'v 1.0.0', - ref: 'master' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('Tag name invalid') - end - - it 'should return 400 if tag already exists' do - post api("/projects/#{project.id}/repository/tags", user), - tag_name: 'v8.0.0', - ref: 'master' - expect(response.status).to eq(201) - post api("/projects/#{project.id}/repository/tags", user), - tag_name: 'v8.0.0', - ref: 'master' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('Tag already exists') - end - - it 'should return 400 if ref name is invalid' do - post api("/projects/#{project.id}/repository/tags", user), - tag_name: 'mytag', - ref: 'foo' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('Invalid reference name') - end - end - - describe "GET /projects/:id/repository/tree" do - context "authorized user" do - before { project.team << [user2, :reporter] } - - it "should return project commits" do - get api("/projects/#{project.id}/repository/tree", user) - expect(response.status).to eq(200) - - expect(json_response).to be_an Array - expect(json_response.first['name']).to eq('encoding') - expect(json_response.first['type']).to eq('tree') - expect(json_response.first['mode']).to eq('040000') - end - - it 'should return a 404 for unknown ref' do - get api("/projects/#{project.id}/repository/tree?ref_name=foo", user) - expect(response.status).to eq(404) - - expect(json_response).to be_an Object - json_response['message'] == '404 Tree Not Found' - end - end - - context "unauthorized user" do - it "should not return project commits" do - get api("/projects/#{project.id}/repository/tree") - expect(response.status).to eq(401) - end - end - end - - describe "GET /projects/:id/repository/blobs/:sha" do - it "should get the raw file contents" do - get api("/projects/#{project.id}/repository/blobs/master?filepath=README.md", user) - expect(response.status).to eq(200) - end - - it "should return 404 for invalid branch_name" do - get api("/projects/#{project.id}/repository/blobs/invalid_branch_name?filepath=README.md", user) - expect(response.status).to eq(404) - end - - it "should return 404 for invalid file" do - get api("/projects/#{project.id}/repository/blobs/master?filepath=README.invalid", user) - expect(response.status).to eq(404) - end - - it "should return a 400 error if filepath is missing" do - get api("/projects/#{project.id}/repository/blobs/master", user) - expect(response.status).to eq(400) - end - end - - describe "GET /projects/:id/repository/commits/:sha/blob" do - it "should get the raw file contents" do - get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.md", user) - expect(response.status).to eq(200) - end - end - - describe "GET /projects/:id/repository/raw_blobs/:sha" do - it "should get the raw file contents" do - get api("/projects/#{project.id}/repository/raw_blobs/#{sample_blob.oid}", user) - expect(response.status).to eq(200) - end - - it 'should return a 404 for unknown blob' do - get api("/projects/#{project.id}/repository/raw_blobs/123456", user) - expect(response.status).to eq(404) - - expect(json_response).to be_an Object - json_response['message'] == '404 Blob Not Found' - end - end - - describe "GET /projects/:id/repository/archive(.:format)?:sha" do - it "should get the archive" do - get api("/projects/#{project.id}/repository/archive", user) - repo_name = project.repository.name.gsub("\.git", "") - expect(response.status).to eq(200) - expect(response.headers['Content-Disposition']).to match(/filename\=\"#{repo_name}\-[^\.]+\.tar.gz\"/) - expect(response.content_type).to eq(MIME::Types.type_for('file.tar.gz').first.content_type) - end - - it "should get the archive.zip" do - get api("/projects/#{project.id}/repository/archive.zip", user) - repo_name = project.repository.name.gsub("\.git", "") - expect(response.status).to eq(200) - expect(response.headers['Content-Disposition']).to match(/filename\=\"#{repo_name}\-[^\.]+\.zip\"/) - expect(response.content_type).to eq(MIME::Types.type_for('file.zip').first.content_type) - end - - it "should get the archive.tar.bz2" do - get api("/projects/#{project.id}/repository/archive.tar.bz2", user) - repo_name = project.repository.name.gsub("\.git", "") - expect(response.status).to eq(200) - expect(response.headers['Content-Disposition']).to match(/filename\=\"#{repo_name}\-[^\.]+\.tar.bz2\"/) - expect(response.content_type).to eq(MIME::Types.type_for('file.tar.bz2').first.content_type) - end - - it "should return 404 for invalid sha" do - get api("/projects/#{project.id}/repository/archive/?sha=xxx", user) - expect(response.status).to eq(404) - end - end - - describe 'GET /projects/:id/repository/compare' do - it "should compare branches" do - get api("/projects/#{project.id}/repository/compare", user), from: 'master', to: 'feature' - expect(response.status).to eq(200) - expect(json_response['commits']).to be_present - expect(json_response['diffs']).to be_present - end - - it "should compare tags" do - get api("/projects/#{project.id}/repository/compare", user), from: 'v1.0.0', to: 'v1.1.0' - expect(response.status).to eq(200) - expect(json_response['commits']).to be_present - expect(json_response['diffs']).to be_present - end - - it "should compare commits" do - get api("/projects/#{project.id}/repository/compare", user), from: sample_commit.id, to: sample_commit.parent_id - expect(response.status).to eq(200) - expect(json_response['commits']).to be_empty - expect(json_response['diffs']).to be_empty - expect(json_response['compare_same_ref']).to be_falsey - end - - it "should compare commits in reverse order" do - get api("/projects/#{project.id}/repository/compare", user), from: sample_commit.parent_id, to: sample_commit.id - expect(response.status).to eq(200) - expect(json_response['commits']).to be_present - expect(json_response['diffs']).to be_present - end - - it "should compare same refs" do - get api("/projects/#{project.id}/repository/compare", user), from: 'master', to: 'master' - expect(response.status).to eq(200) - expect(json_response['commits']).to be_empty - expect(json_response['diffs']).to be_empty - expect(json_response['compare_same_ref']).to be_truthy - end - end - - describe 'GET /projects/:id/repository/contributors' do - it 'should return valid data' do - get api("/projects/#{project.id}/repository/contributors", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - contributor = json_response.first - expect(contributor['email']).to eq('dmitriy.zaporozhets@gmail.com') - expect(contributor['name']).to eq('Dmitriy Zaporozhets') - expect(contributor['commits']).to eq(13) - expect(contributor['additions']).to eq(0) - expect(contributor['deletions']).to eq(0) - end - end -end diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb deleted file mode 100644 index 51c543578df747fec3bb0a5e5d3a7103248137a5..0000000000000000000000000000000000000000 --- a/spec/requests/api/services_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -require "spec_helper" - -describe API::API, api: true do - include ApiHelpers - let(:user) { create(:user) } - let(:project) {create(:project, creator_id: user.id, namespace: user.namespace) } - - describe "POST /projects/:id/services/gitlab-ci" do - it "should update gitlab-ci settings" do - put api("/projects/#{project.id}/services/gitlab-ci", user), token: 'secret-token', project_url: "http://ci.example.com/projects/1" - - expect(response.status).to eq(200) - end - - it "should return if required fields missing" do - put api("/projects/#{project.id}/services/gitlab-ci", user), project_url: "http://ci.example.com/projects/1", active: true - - expect(response.status).to eq(400) - end - end - - describe "DELETE /projects/:id/services/gitlab-ci" do - it "should update gitlab-ci settings" do - delete api("/projects/#{project.id}/services/gitlab-ci", user) - - expect(response.status).to eq(200) - expect(project.gitlab_ci_service).to be_nil - end - end - - describe 'PUT /projects/:id/services/hipchat' do - it 'should update hipchat settings' do - put api("/projects/#{project.id}/services/hipchat", user), - token: 'secret-token', room: 'test' - - expect(response.status).to eq(200) - expect(project.hipchat_service).not_to be_nil - end - - it 'should return if required fields missing' do - put api("/projects/#{project.id}/services/gitlab-ci", user), - token: 'secret-token', active: true - - expect(response.status).to eq(400) - end - end - - describe 'DELETE /projects/:id/services/hipchat' do - it 'should delete hipchat settings' do - delete api("/projects/#{project.id}/services/hipchat", user) - - expect(response.status).to eq(200) - expect(project.hipchat_service).to be_nil - end - end -end diff --git a/spec/requests/api/session_spec.rb b/spec/requests/api/session_spec.rb deleted file mode 100644 index fbd57b34a58d32308e969cdddf4b7b681011b645..0000000000000000000000000000000000000000 --- a/spec/requests/api/session_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - - let(:user) { create(:user) } - - describe "POST /session" do - context "when valid password" do - it "should return private token" do - post api("/session"), email: user.email, password: '12345678' - expect(response.status).to eq(201) - - expect(json_response['email']).to eq(user.email) - expect(json_response['private_token']).to eq(user.private_token) - expect(json_response['is_admin']).to eq(user.is_admin?) - expect(json_response['can_create_project']).to eq(user.can_create_project?) - expect(json_response['can_create_group']).to eq(user.can_create_group?) - end - end - - context 'when email has case-typo and password is valid' do - it 'should return private token' do - post api('/session'), email: user.email.upcase, password: '12345678' - expect(response.status).to eq 201 - - expect(json_response['email']).to eq user.email - expect(json_response['private_token']).to eq user.private_token - expect(json_response['is_admin']).to eq user.is_admin? - expect(json_response['can_create_project']).to eq user.can_create_project? - expect(json_response['can_create_group']).to eq user.can_create_group? - end - end - - context 'when login has case-typo and password is valid' do - it 'should return private token' do - post api('/session'), login: user.username.upcase, password: '12345678' - expect(response.status).to eq 201 - - expect(json_response['email']).to eq user.email - expect(json_response['private_token']).to eq user.private_token - expect(json_response['is_admin']).to eq user.is_admin? - expect(json_response['can_create_project']).to eq user.can_create_project? - expect(json_response['can_create_group']).to eq user.can_create_group? - end - end - - context "when invalid password" do - it "should return authentication error" do - post api("/session"), email: user.email, password: '123' - expect(response.status).to eq(401) - - expect(json_response['email']).to be_nil - expect(json_response['private_token']).to be_nil - end - end - - context "when empty password" do - it "should return authentication error" do - post api("/session"), email: user.email - expect(response.status).to eq(401) - - expect(json_response['email']).to be_nil - expect(json_response['private_token']).to be_nil - end - end - - context "when empty name" do - it "should return authentication error" do - post api("/session"), password: user.password - expect(response.status).to eq(401) - - expect(json_response['email']).to be_nil - expect(json_response['private_token']).to be_nil - end - end - end -end diff --git a/spec/requests/api/system_hooks_spec.rb b/spec/requests/api/system_hooks_spec.rb deleted file mode 100644 index a9d86bbce6c9165d715cecd235be557d27f5519a..0000000000000000000000000000000000000000 --- a/spec/requests/api/system_hooks_spec.rb +++ /dev/null @@ -1,81 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - - let(:user) { create(:user) } - let(:admin) { create(:admin) } - let!(:hook) { create(:system_hook, url: "http://example.com") } - - before { stub_request(:post, hook.url) } - - describe "GET /hooks" do - context "when no user" do - it "should return authentication error" do - get api("/hooks") - expect(response.status).to eq(401) - end - end - - context "when not an admin" do - it "should return forbidden error" do - get api("/hooks", user) - expect(response.status).to eq(403) - end - end - - context "when authenticated as admin" do - it "should return an array of hooks" do - get api("/hooks", admin) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['url']).to eq(hook.url) - end - end - end - - describe "POST /hooks" do - it "should create new hook" do - expect { - post api("/hooks", admin), url: 'http://example.com' - }.to change { SystemHook.count }.by(1) - end - - it "should respond with 400 if url not given" do - post api("/hooks", admin) - expect(response.status).to eq(400) - end - - it "should not create new hook without url" do - expect { - post api("/hooks", admin) - }.to_not change { SystemHook.count } - end - end - - describe "GET /hooks/:id" do - it "should return hook by id" do - get api("/hooks/#{hook.id}", admin) - expect(response.status).to eq(200) - expect(json_response['event_name']).to eq('project_create') - end - - it "should return 404 on failure" do - get api("/hooks/404", admin) - expect(response.status).to eq(404) - end - end - - describe "DELETE /hooks/:id" do - it "should delete a hook" do - expect { - delete api("/hooks/#{hook.id}", admin) - }.to change { SystemHook.count }.by(-1) - end - - it "should return success if hook id not found" do - delete api("/hooks/12345", admin) - expect(response.status).to eq(200) - end - end -end diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb deleted file mode 100644 index e6d5545f81284d501473c97ac9be8bba0c8639a6..0000000000000000000000000000000000000000 --- a/spec/requests/api/users_spec.rb +++ /dev/null @@ -1,524 +0,0 @@ -require 'spec_helper' - -describe API::API, api: true do - include ApiHelpers - - let(:user) { create(:user) } - let(:admin) { create(:admin) } - let(:key) { create(:key, user: user) } - - describe "GET /users" do - context "when unauthenticated" do - it "should return authentication error" do - get api("/users") - expect(response.status).to eq(401) - end - end - - context "when authenticated" do - it "should return an array of users" do - get api("/users", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - username = user.username - expect(json_response.detect { - |user| user['username'] == username - }['username']).to eq(username) - end - end - - context "when admin" do - it "should return an array of users" do - get api("/users", admin) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first.keys).to include 'email' - expect(json_response.first.keys).to include 'identities' - expect(json_response.first.keys).to include 'can_create_project' - end - end - end - - describe "GET /users/:id" do - it "should return a user by id" do - get api("/users/#{user.id}", user) - expect(response.status).to eq(200) - expect(json_response['username']).to eq(user.username) - end - - it "should return a 401 if unauthenticated" do - get api("/users/9998") - expect(response.status).to eq(401) - end - - it "should return a 404 error if user id not found" do - get api("/users/9999", user) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Not found') - end - end - - describe "POST /users" do - before{ admin } - - it "should create user" do - expect { - post api("/users", admin), attributes_for(:user, projects_limit: 3) - }.to change { User.count }.by(1) - end - - it "should create user with correct attributes" do - post api('/users', admin), attributes_for(:user, admin: true, can_create_group: true) - expect(response.status).to eq(201) - user_id = json_response['id'] - new_user = User.find(user_id) - expect(new_user).not_to eq(nil) - expect(new_user.admin).to eq(true) - expect(new_user.can_create_group).to eq(true) - end - - it "should create non-admin user" do - post api('/users', admin), attributes_for(:user, admin: false, can_create_group: false) - expect(response.status).to eq(201) - user_id = json_response['id'] - new_user = User.find(user_id) - expect(new_user).not_to eq(nil) - expect(new_user.admin).to eq(false) - expect(new_user.can_create_group).to eq(false) - end - - it "should create non-admin users by default" do - post api('/users', admin), attributes_for(:user) - expect(response.status).to eq(201) - user_id = json_response['id'] - new_user = User.find(user_id) - expect(new_user).not_to eq(nil) - expect(new_user.admin).to eq(false) - end - - it "should return 201 Created on success" do - post api("/users", admin), attributes_for(:user, projects_limit: 3) - expect(response.status).to eq(201) - end - - it "should not create user with invalid email" do - post api('/users', admin), - email: 'invalid email', - password: 'password', - name: 'test' - expect(response.status).to eq(400) - end - - it 'should return 400 error if name not given' do - post api('/users', admin), email: 'test@example.com', password: 'pass1234' - expect(response.status).to eq(400) - end - - it 'should return 400 error if password not given' do - post api('/users', admin), email: 'test@example.com', name: 'test' - expect(response.status).to eq(400) - end - - it "should return 400 error if email not given" do - post api('/users', admin), password: 'pass1234', name: 'test' - expect(response.status).to eq(400) - end - - it 'should return 400 error if user does not validate' do - post api('/users', admin), - password: 'pass', - email: 'test@example.com', - username: 'test!', - name: 'test', - bio: 'g' * 256, - projects_limit: -1 - expect(response.status).to eq(400) - expect(json_response['message']['password']). - to eq(['is too short (minimum is 8 characters)']) - expect(json_response['message']['bio']). - to eq(['is too long (maximum is 255 characters)']) - expect(json_response['message']['projects_limit']). - to eq(['must be greater than or equal to 0']) - expect(json_response['message']['username']). - to eq([Gitlab::Regex.send(:namespace_regex_message)]) - end - - it "shouldn't available for non admin users" do - post api("/users", user), attributes_for(:user) - expect(response.status).to eq(403) - end - - context 'with existing user' do - before do - post api('/users', admin), - email: 'test@example.com', - password: 'password', - username: 'test', - name: 'foo' - end - - it 'should return 409 conflict error if user with same email exists' do - expect { - post api('/users', admin), - name: 'foo', - email: 'test@example.com', - password: 'password', - username: 'foo' - }.to change { User.count }.by(0) - expect(response.status).to eq(409) - expect(json_response['message']).to eq('Email has already been taken') - end - - it 'should return 409 conflict error if same username exists' do - expect do - post api('/users', admin), - name: 'foo', - email: 'foo@example.com', - password: 'password', - username: 'test' - end.to change { User.count }.by(0) - expect(response.status).to eq(409) - expect(json_response['message']).to eq('Username has already been taken') - end - end - end - - describe "GET /users/sign_up" do - - it "should redirect to sign in page" do - get "/users/sign_up" - expect(response.status).to eq(302) - expect(response).to redirect_to(new_user_session_path) - end - end - - describe "PUT /users/:id" do - let!(:admin_user) { create(:admin) } - - before { admin } - - it "should update user with new bio" do - put api("/users/#{user.id}", admin), {bio: 'new test bio'} - expect(response.status).to eq(200) - expect(json_response['bio']).to eq('new test bio') - expect(user.reload.bio).to eq('new test bio') - end - - it 'should update user with his own email' do - put api("/users/#{user.id}", admin), email: user.email - expect(response.status).to eq(200) - expect(json_response['email']).to eq(user.email) - expect(user.reload.email).to eq(user.email) - end - - it 'should update user with his own username' do - put api("/users/#{user.id}", admin), username: user.username - expect(response.status).to eq(200) - expect(json_response['username']).to eq(user.username) - expect(user.reload.username).to eq(user.username) - end - - it "should update admin status" do - put api("/users/#{user.id}", admin), {admin: true} - expect(response.status).to eq(200) - expect(json_response['is_admin']).to eq(true) - expect(user.reload.admin).to eq(true) - end - - it "should not update admin status" do - put api("/users/#{admin_user.id}", admin), {can_create_group: false} - expect(response.status).to eq(200) - expect(json_response['is_admin']).to eq(true) - expect(admin_user.reload.admin).to eq(true) - expect(admin_user.can_create_group).to eq(false) - end - - it "should not allow invalid update" do - put api("/users/#{user.id}", admin), {email: 'invalid email'} - expect(response.status).to eq(400) - expect(user.reload.email).not_to eq('invalid email') - end - - it "shouldn't available for non admin users" do - put api("/users/#{user.id}", user), attributes_for(:user) - expect(response.status).to eq(403) - end - - it "should return 404 for non-existing user" do - put api("/users/999999", admin), {bio: 'update should fail'} - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Not found') - end - - it 'should return 400 error if user does not validate' do - put api("/users/#{user.id}", admin), - password: 'pass', - email: 'test@example.com', - username: 'test!', - name: 'test', - bio: 'g' * 256, - projects_limit: -1 - expect(response.status).to eq(400) - expect(json_response['message']['password']). - to eq(['is too short (minimum is 8 characters)']) - expect(json_response['message']['bio']). - to eq(['is too long (maximum is 255 characters)']) - expect(json_response['message']['projects_limit']). - to eq(['must be greater than or equal to 0']) - expect(json_response['message']['username']). - to eq([Gitlab::Regex.send(:namespace_regex_message)]) - end - - context "with existing user" do - before { - post api("/users", admin), { email: 'test@example.com', password: 'password', username: 'test', name: 'test' } - post api("/users", admin), { email: 'foo@bar.com', password: 'password', username: 'john', name: 'john' } - @user = User.all.last - } - - it 'should return 409 conflict error if email address exists' do - put api("/users/#{@user.id}", admin), email: 'test@example.com' - expect(response.status).to eq(409) - expect(@user.reload.email).to eq(@user.email) - end - - it 'should return 409 conflict error if username taken' do - @user_id = User.all.last.id - put api("/users/#{@user.id}", admin), username: 'test' - expect(response.status).to eq(409) - expect(@user.reload.username).to eq(@user.username) - end - end - end - - describe "POST /users/:id/keys" do - before { admin } - - it "should not create invalid ssh key" do - post api("/users/#{user.id}/keys", admin), { title: "invalid key" } - expect(response.status).to eq(400) - expect(json_response['message']).to eq('400 (Bad request) "key" not given') - end - - it 'should not create key without title' do - post api("/users/#{user.id}/keys", admin), key: 'some key' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('400 (Bad request) "title" not given') - end - - it "should create ssh key" do - key_attrs = attributes_for :key - expect { - post api("/users/#{user.id}/keys", admin), key_attrs - }.to change{ user.keys.count }.by(1) - end - end - - describe 'GET /user/:uid/keys' do - before { admin } - - context 'when unauthenticated' do - it 'should return authentication error' do - get api("/users/#{user.id}/keys") - expect(response.status).to eq(401) - end - end - - context 'when authenticated' do - it 'should return 404 for non-existing user' do - get api('/users/999999/keys', admin) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 User Not Found') - end - - it 'should return array of ssh keys' do - user.keys << key - user.save - get api("/users/#{user.id}/keys", admin) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first['title']).to eq(key.title) - end - end - end - - describe 'DELETE /user/:uid/keys/:id' do - before { admin } - - context 'when unauthenticated' do - it 'should return authentication error' do - delete api("/users/#{user.id}/keys/42") - expect(response.status).to eq(401) - end - end - - context 'when authenticated' do - it 'should delete existing key' do - user.keys << key - user.save - expect { - delete api("/users/#{user.id}/keys/#{key.id}", admin) - }.to change { user.keys.count }.by(-1) - expect(response.status).to eq(200) - end - - it 'should return 404 error if user not found' do - user.keys << key - user.save - delete api("/users/999999/keys/#{key.id}", admin) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 User Not Found') - end - - it 'should return 404 error if key not foud' do - delete api("/users/#{user.id}/keys/42", admin) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Key Not Found') - end - end - end - - describe "DELETE /users/:id" do - before { admin } - - it "should delete user" do - delete api("/users/#{user.id}", admin) - expect(response.status).to eq(200) - expect { User.find(user.id) }.to raise_error ActiveRecord::RecordNotFound - expect(json_response['email']).to eq(user.email) - end - - it "should not delete for unauthenticated user" do - delete api("/users/#{user.id}") - expect(response.status).to eq(401) - end - - it "shouldn't available for non admin users" do - delete api("/users/#{user.id}", user) - expect(response.status).to eq(403) - end - - it "should return 404 for non-existing user" do - delete api("/users/999999", admin) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 User Not Found') - end - end - - describe "GET /user" do - it "should return current user" do - get api("/user", user) - expect(response.status).to eq(200) - expect(json_response['email']).to eq(user.email) - expect(json_response['is_admin']).to eq(user.is_admin?) - expect(json_response['can_create_project']).to eq(user.can_create_project?) - expect(json_response['can_create_group']).to eq(user.can_create_group?) - expect(json_response['projects_limit']).to eq(user.projects_limit) - end - - it "should return 401 error if user is unauthenticated" do - get api("/user") - expect(response.status).to eq(401) - end - end - - describe "GET /user/keys" do - context "when unauthenticated" do - it "should return authentication error" do - get api("/user/keys") - expect(response.status).to eq(401) - end - end - - context "when authenticated" do - it "should return array of ssh keys" do - user.keys << key - user.save - get api("/user/keys", user) - expect(response.status).to eq(200) - expect(json_response).to be_an Array - expect(json_response.first["title"]).to eq(key.title) - end - end - end - - describe "GET /user/keys/:id" do - it "should return single key" do - user.keys << key - user.save - get api("/user/keys/#{key.id}", user) - expect(response.status).to eq(200) - expect(json_response["title"]).to eq(key.title) - end - - it "should return 404 Not Found within invalid ID" do - get api("/user/keys/42", user) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Not found') - end - - it "should return 404 error if admin accesses user's ssh key" do - user.keys << key - user.save - admin - get api("/user/keys/#{key.id}", admin) - expect(response.status).to eq(404) - expect(json_response['message']).to eq('404 Not found') - end - end - - describe "POST /user/keys" do - it "should create ssh key" do - key_attrs = attributes_for :key - expect { - post api("/user/keys", user), key_attrs - }.to change{ user.keys.count }.by(1) - expect(response.status).to eq(201) - end - - it "should return a 401 error if unauthorized" do - post api("/user/keys"), title: 'some title', key: 'some key' - expect(response.status).to eq(401) - end - - it "should not create ssh key without key" do - post api("/user/keys", user), title: 'title' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('400 (Bad request) "key" not given') - end - - it 'should not create ssh key without title' do - post api('/user/keys', user), key: 'some key' - expect(response.status).to eq(400) - expect(json_response['message']).to eq('400 (Bad request) "title" not given') - end - - it "should not create ssh key without title" do - post api("/user/keys", user), key: "somekey" - expect(response.status).to eq(400) - end - end - - describe "DELETE /user/keys/:id" do - it "should delete existed key" do - user.keys << key - user.save - expect { - delete api("/user/keys/#{key.id}", user) - }.to change{user.keys.count}.by(-1) - expect(response.status).to eq(200) - end - - it "should return success if key ID not found" do - delete api("/user/keys/42", user) - expect(response.status).to eq(200) - end - - it "should return 401 error if unauthorized" do - user.keys << key - user.save - delete api("/user/keys/#{key.id}") - expect(response.status).to eq(401) - end - end -end diff --git a/spec/routing/admin_routing_spec.rb b/spec/routing/admin_routing_spec.rb deleted file mode 100644 index bf8abcfb00f86ba4293748f0a5e232c82357ff6e..0000000000000000000000000000000000000000 --- a/spec/routing/admin_routing_spec.rb +++ /dev/null @@ -1,121 +0,0 @@ -require 'spec_helper' - -# team_update_admin_user PUT /admin/users/:id/team_update(.:format) admin/users#team_update -# block_admin_user PUT /admin/users/:id/block(.:format) admin/users#block -# unblock_admin_user PUT /admin/users/:id/unblock(.:format) admin/users#unblock -# admin_users GET /admin/users(.:format) admin/users#index -# POST /admin/users(.:format) admin/users#create -# new_admin_user GET /admin/users/new(.:format) admin/users#new -# edit_admin_user GET /admin/users/:id/edit(.:format) admin/users#edit -# admin_user GET /admin/users/:id(.:format) admin/users#show -# PUT /admin/users/:id(.:format) admin/users#update -# DELETE /admin/users/:id(.:format) admin/users#destroy -describe Admin::UsersController, "routing" do - it "to #team_update" do - expect(put("/admin/users/1/team_update")).to route_to('admin/users#team_update', id: '1') - end - - it "to #block" do - expect(put("/admin/users/1/block")).to route_to('admin/users#block', id: '1') - end - - it "to #unblock" do - expect(put("/admin/users/1/unblock")).to route_to('admin/users#unblock', id: '1') - end - - it "to #index" do - expect(get("/admin/users")).to route_to('admin/users#index') - end - - it "to #show" do - expect(get("/admin/users/1")).to route_to('admin/users#show', id: '1') - end - - it "to #create" do - expect(post("/admin/users")).to route_to('admin/users#create') - end - - it "to #new" do - expect(get("/admin/users/new")).to route_to('admin/users#new') - end - - it "to #edit" do - expect(get("/admin/users/1/edit")).to route_to('admin/users#edit', id: '1') - end - - it "to #show" do - expect(get("/admin/users/1")).to route_to('admin/users#show', id: '1') - end - - it "to #update" do - expect(put("/admin/users/1")).to route_to('admin/users#update', id: '1') - end - - it "to #destroy" do - expect(delete("/admin/users/1")).to route_to('admin/users#destroy', id: '1') - end -end - -# team_admin_project GET /admin/projects/:id/team(.:format) admin/projects#team {id: /[^\/]+/} -# team_update_admin_project PUT /admin/projects/:id/team_update(.:format) admin/projects#team_update {id: /[^\/]+/} -# admin_projects GET /admin/projects(.:format) admin/projects#index {id: /[^\/]+/} -# POST /admin/projects(.:format) admin/projects#create {id: /[^\/]+/} -# new_admin_project GET /admin/projects/new(.:format) admin/projects#new {id: /[^\/]+/} -# edit_admin_project GET /admin/projects/:id/edit(.:format) admin/projects#edit {id: /[^\/]+/} -# admin_project GET /admin/projects/:id(.:format) admin/projects#show {id: /[^\/]+/} -# PUT /admin/projects/:id(.:format) admin/projects#update {id: /[^\/]+/} -# DELETE /admin/projects/:id(.:format) admin/projects#destroy {id: /[^\/]+/} -describe Admin::ProjectsController, "routing" do - it "to #index" do - expect(get("/admin/projects")).to route_to('admin/projects#index') - end - - it "to #show" do - expect(get("/admin/projects/gitlab")).to route_to('admin/projects#show', namespace_id: 'gitlab') - end -end - -# admin_hook_test GET /admin/hooks/:hook_id/test(.:format) admin/hooks#test -# admin_hooks GET /admin/hooks(.:format) admin/hooks#index -# POST /admin/hooks(.:format) admin/hooks#create -# admin_hook DELETE /admin/hooks/:id(.:format) admin/hooks#destroy -describe Admin::HooksController, "routing" do - it "to #test" do - expect(get("/admin/hooks/1/test")).to route_to('admin/hooks#test', hook_id: '1') - end - - it "to #index" do - expect(get("/admin/hooks")).to route_to('admin/hooks#index') - end - - it "to #create" do - expect(post("/admin/hooks")).to route_to('admin/hooks#create') - end - - it "to #destroy" do - expect(delete("/admin/hooks/1")).to route_to('admin/hooks#destroy', id: '1') - end - -end - -# admin_logs GET /admin/logs(.:format) admin/logs#show -describe Admin::LogsController, "routing" do - it "to #show" do - expect(get("/admin/logs")).to route_to('admin/logs#show') - end -end - -# admin_background_jobs GET /admin/background_jobs(.:format) admin/background_jobs#show -describe Admin::BackgroundJobsController, "routing" do - it "to #show" do - expect(get("/admin/background_jobs")).to route_to('admin/background_jobs#show') - end -end - -# admin_root /admin(.:format) admin/dashboard#index -describe Admin::DashboardController, "routing" do - it "to #index" do - expect(get("/admin")).to route_to('admin/dashboard#index') - end -end - diff --git a/spec/routing/notifications_routing_spec.rb b/spec/routing/notifications_routing_spec.rb deleted file mode 100644 index 24592942a967e77b20d38dc6391550af2890239d..0000000000000000000000000000000000000000 --- a/spec/routing/notifications_routing_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "spec_helper" - -describe Profiles::NotificationsController do - describe "routing" do - it "routes to #show" do - expect(get("/profile/notifications")).to route_to("profiles/notifications#show") - end - - it "routes to #update" do - expect(put("/profile/notifications")).to route_to("profiles/notifications#update") - end - end -end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb deleted file mode 100644 index 042352311da9dfbe843ea785228a1d5bd0e61bf2..0000000000000000000000000000000000000000 --- a/spec/routing/project_routing_spec.rb +++ /dev/null @@ -1,492 +0,0 @@ -require 'spec_helper' - -# Shared examples for a resource inside a Project -# -# By default it tests all the default REST actions: index, create, new, edit, -# show, update, and destroy. You can remove actions by customizing the -# `actions` variable. -# -# It also expects a `controller` variable to be available which defines both -# the path to the resource as well as the controller name. -# -# Examples -# -# # Default behavior -# it_behaves_like 'RESTful project resources' do -# let(:controller) { 'issues' } -# end -# -# # Customizing actions -# it_behaves_like 'RESTful project resources' do -# let(:actions) { [:index] } -# let(:controller) { 'issues' } -# end -shared_examples 'RESTful project resources' do - let(:actions) { [:index, :create, :new, :edit, :show, :update, :destroy] } - - it 'to #index' do - expect(get("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#index", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:index) - end - - it 'to #create' do - expect(post("/gitlab/gitlabhq/#{controller}")).to route_to("projects/#{controller}#create", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:create) - end - - it 'to #new' do - expect(get("/gitlab/gitlabhq/#{controller}/new")).to route_to("projects/#{controller}#new", namespace_id: 'gitlab', project_id: 'gitlabhq') if actions.include?(:new) - end - - it 'to #edit' do - expect(get("/gitlab/gitlabhq/#{controller}/1/edit")).to route_to("projects/#{controller}#edit", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:edit) - end - - it 'to #show' do - expect(get("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#show", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:show) - end - - it 'to #update' do - expect(put("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#update", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:update) - end - - it 'to #destroy' do - expect(delete("/gitlab/gitlabhq/#{controller}/1")).to route_to("projects/#{controller}#destroy", namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') if actions.include?(:destroy) - end -end - -# projects POST /projects(.:format) projects#create -# new_project GET /projects/new(.:format) projects#new -# files_project GET /:id/files(.:format) projects#files -# edit_project GET /:id/edit(.:format) projects#edit -# project GET /:id(.:format) projects#show -# PUT /:id(.:format) projects#update -# DELETE /:id(.:format) projects#destroy -# markdown_preview_project POST /:id/markdown_preview(.:format) projects#markdown_preview -describe ProjectsController, 'routing' do - it 'to #create' do - expect(post('/projects')).to route_to('projects#create') - end - - it 'to #new' do - expect(get('/projects/new')).to route_to('projects#new') - end - - it 'to #edit' do - expect(get('/gitlab/gitlabhq/edit')).to route_to('projects#edit', namespace_id: 'gitlab', id: 'gitlabhq') - end - - it 'to #autocomplete_sources' do - expect(get('/gitlab/gitlabhq/autocomplete_sources')).to route_to('projects#autocomplete_sources', namespace_id: 'gitlab', id: 'gitlabhq') - end - - it 'to #show' do - expect(get('/gitlab/gitlabhq')).to route_to('projects#show', namespace_id: 'gitlab', id: 'gitlabhq') - end - - it 'to #update' do - expect(put('/gitlab/gitlabhq')).to route_to('projects#update', namespace_id: 'gitlab', id: 'gitlabhq') - end - - it 'to #destroy' do - expect(delete('/gitlab/gitlabhq')).to route_to('projects#destroy', namespace_id: 'gitlab', id: 'gitlabhq') - end - - it 'to #markdown_preview' do - expect(post('/gitlab/gitlabhq/markdown_preview')).to( - route_to('projects#markdown_preview', namespace_id: 'gitlab', id: 'gitlabhq') - ) - end -end - -# pages_project_wikis GET /:project_id/wikis/pages(.:format) projects/wikis#pages -# history_project_wiki GET /:project_id/wikis/:id/history(.:format) projects/wikis#history -# project_wikis POST /:project_id/wikis(.:format) projects/wikis#create -# edit_project_wiki GET /:project_id/wikis/:id/edit(.:format) projects/wikis#edit -# project_wiki GET /:project_id/wikis/:id(.:format) projects/wikis#show -# DELETE /:project_id/wikis/:id(.:format) projects/wikis#destroy -describe Projects::WikisController, 'routing' do - it 'to #pages' do - expect(get('/gitlab/gitlabhq/wikis/pages')).to route_to('projects/wikis#pages', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #history' do - expect(get('/gitlab/gitlabhq/wikis/1/history')).to route_to('projects/wikis#history', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - - it_behaves_like 'RESTful project resources' do - let(:actions) { [:create, :edit, :show, :destroy] } - let(:controller) { 'wikis' } - end -end - -# branches_project_repository GET /:project_id/repository/branches(.:format) projects/repositories#branches -# tags_project_repository GET /:project_id/repository/tags(.:format) projects/repositories#tags -# archive_project_repository GET /:project_id/repository/archive(.:format) projects/repositories#archive -# edit_project_repository GET /:project_id/repository/edit(.:format) projects/repositories#edit -describe Projects::RepositoriesController, 'routing' do - it 'to #archive' do - expect(get('/gitlab/gitlabhq/repository/archive')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #archive format:zip' do - expect(get('/gitlab/gitlabhq/repository/archive.zip')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'zip') - end - - it 'to #archive format:tar.bz2' do - expect(get('/gitlab/gitlabhq/repository/archive.tar.bz2')).to route_to('projects/repositories#archive', namespace_id: 'gitlab', project_id: 'gitlabhq', format: 'tar.bz2') - end - - it 'to #show' do - expect(get('/gitlab/gitlabhq/repository')).to route_to('projects/repositories#show', namespace_id: 'gitlab', project_id: 'gitlabhq') - end -end - -describe Projects::BranchesController, 'routing' do - it 'to #branches' do - expect(get('/gitlab/gitlabhq/branches')).to route_to('projects/branches#index', namespace_id: 'gitlab', project_id: 'gitlabhq') - expect(delete('/gitlab/gitlabhq/branches/feature%2345')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45') - expect(delete('/gitlab/gitlabhq/branches/feature%2B45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45') - expect(delete('/gitlab/gitlabhq/branches/feature@45')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45') - expect(delete('/gitlab/gitlabhq/branches/feature%2345/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz') - expect(delete('/gitlab/gitlabhq/branches/feature%2B45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz') - expect(delete('/gitlab/gitlabhq/branches/feature@45/foo/bar/baz')).to route_to('projects/branches#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz') - end -end - -describe Projects::TagsController, 'routing' do - it 'to #tags' do - expect(get('/gitlab/gitlabhq/tags')).to route_to('projects/tags#index', namespace_id: 'gitlab', project_id: 'gitlabhq') - expect(delete('/gitlab/gitlabhq/tags/feature%2345')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45') - expect(delete('/gitlab/gitlabhq/tags/feature%2B45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45') - expect(delete('/gitlab/gitlabhq/tags/feature@45')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45') - expect(delete('/gitlab/gitlabhq/tags/feature%2345/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45/foo/bar/baz') - expect(delete('/gitlab/gitlabhq/tags/feature%2B45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45/foo/bar/baz') - expect(delete('/gitlab/gitlabhq/tags/feature@45/foo/bar/baz')).to route_to('projects/tags#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45/foo/bar/baz') - end -end - - -# project_deploy_keys GET /:project_id/deploy_keys(.:format) deploy_keys#index -# POST /:project_id/deploy_keys(.:format) deploy_keys#create -# new_project_deploy_key GET /:project_id/deploy_keys/new(.:format) deploy_keys#new -# project_deploy_key GET /:project_id/deploy_keys/:id(.:format) deploy_keys#show -# DELETE /:project_id/deploy_keys/:id(.:format) deploy_keys#destroy -describe Projects::DeployKeysController, 'routing' do - it_behaves_like 'RESTful project resources' do - let(:actions) { [:index, :show, :new, :create] } - let(:controller) { 'deploy_keys' } - end -end - -# project_protected_branches GET /:project_id/protected_branches(.:format) protected_branches#index -# POST /:project_id/protected_branches(.:format) protected_branches#create -# project_protected_branch DELETE /:project_id/protected_branches/:id(.:format) protected_branches#destroy -describe Projects::ProtectedBranchesController, 'routing' do - it_behaves_like 'RESTful project resources' do - let(:actions) { [:index, :create, :destroy] } - let(:controller) { 'protected_branches' } - end -end - -# switch_project_refs GET /:project_id/refs/switch(.:format) refs#switch -# logs_tree_project_ref GET /:project_id/refs/:id/logs_tree(.:format) refs#logs_tree -# logs_file_project_ref GET /:project_id/refs/:id/logs_tree/:path(.:format) refs#logs_tree -describe Projects::RefsController, 'routing' do - it 'to #switch' do - expect(get('/gitlab/gitlabhq/refs/switch')).to route_to('projects/refs#switch', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #logs_tree' do - expect(get('/gitlab/gitlabhq/refs/stable/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable') - expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45') - expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45') - expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45') - expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz') - expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45', path: 'foo/bar/baz') - expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45', path: 'foo/bar/baz') - expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45', path: 'foo/bar/baz') - expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/files.scss')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'files.scss') - end -end - -# diffs_project_merge_request GET /:project_id/merge_requests/:id/diffs(.:format) projects/merge_requests#diffs -# automerge_project_merge_request POST /:project_id/merge_requests/:id/automerge(.:format) projects/merge_requests#automerge -# automerge_check_project_merge_request GET /:project_id/merge_requests/:id/automerge_check(.:format) projects/merge_requests#automerge_check -# branch_from_project_merge_requests GET /:project_id/merge_requests/branch_from(.:format) projects/merge_requests#branch_from -# branch_to_project_merge_requests GET /:project_id/merge_requests/branch_to(.:format) projects/merge_requests#branch_to -# project_merge_requests GET /:project_id/merge_requests(.:format) projects/merge_requests#index -# POST /:project_id/merge_requests(.:format) projects/merge_requests#create -# new_project_merge_request GET /:project_id/merge_requests/new(.:format) projects/merge_requests#new -# edit_project_merge_request GET /:project_id/merge_requests/:id/edit(.:format) projects/merge_requests#edit -# project_merge_request GET /:project_id/merge_requests/:id(.:format) projects/merge_requests#show -# PUT /:project_id/merge_requests/:id(.:format) projects/merge_requests#update -# DELETE /:project_id/merge_requests/:id(.:format) projects/merge_requests#destroy -describe Projects::MergeRequestsController, 'routing' do - it 'to #diffs' do - expect(get('/gitlab/gitlabhq/merge_requests/1/diffs')).to route_to('projects/merge_requests#diffs', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - - it 'to #automerge' do - expect(post('/gitlab/gitlabhq/merge_requests/1/automerge')).to route_to( - 'projects/merge_requests#automerge', - namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1' - ) - end - - it 'to #automerge_check' do - expect(get('/gitlab/gitlabhq/merge_requests/1/automerge_check')).to route_to('projects/merge_requests#automerge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - - it 'to #branch_from' do - expect(get('/gitlab/gitlabhq/merge_requests/branch_from')).to route_to('projects/merge_requests#branch_from', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #branch_to' do - expect(get('/gitlab/gitlabhq/merge_requests/branch_to')).to route_to('projects/merge_requests#branch_to', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #show' do - expect(get('/gitlab/gitlabhq/merge_requests/1.diff')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'diff') - expect(get('/gitlab/gitlabhq/merge_requests/1.patch')).to route_to('projects/merge_requests#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1', format: 'patch') - end - - it_behaves_like 'RESTful project resources' do - let(:controller) { 'merge_requests' } - let(:actions) { [:index, :create, :new, :edit, :show, :update] } - end -end - -# raw_project_snippet GET /:project_id/snippets/:id/raw(.:format) snippets#raw -# project_snippets GET /:project_id/snippets(.:format) snippets#index -# POST /:project_id/snippets(.:format) snippets#create -# new_project_snippet GET /:project_id/snippets/new(.:format) snippets#new -# edit_project_snippet GET /:project_id/snippets/:id/edit(.:format) snippets#edit -# project_snippet GET /:project_id/snippets/:id(.:format) snippets#show -# PUT /:project_id/snippets/:id(.:format) snippets#update -# DELETE /:project_id/snippets/:id(.:format) snippets#destroy -describe SnippetsController, 'routing' do - it 'to #raw' do - expect(get('/gitlab/gitlabhq/snippets/1/raw')).to route_to('projects/snippets#raw', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - - it 'to #index' do - expect(get('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#index', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #create' do - expect(post('/gitlab/gitlabhq/snippets')).to route_to('projects/snippets#create', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #new' do - expect(get('/gitlab/gitlabhq/snippets/new')).to route_to('projects/snippets#new', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #edit' do - expect(get('/gitlab/gitlabhq/snippets/1/edit')).to route_to('projects/snippets#edit', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - - it 'to #show' do - expect(get('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - - it 'to #update' do - expect(put('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#update', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - - it 'to #destroy' do - expect(delete('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end -end - -# test_project_hook GET /:project_id/hooks/:id/test(.:format) hooks#test -# project_hooks GET /:project_id/hooks(.:format) hooks#index -# POST /:project_id/hooks(.:format) hooks#create -# project_hook DELETE /:project_id/hooks/:id(.:format) hooks#destroy -describe Projects::HooksController, 'routing' do - it 'to #test' do - expect(get('/gitlab/gitlabhq/hooks/1/test')).to route_to('projects/hooks#test', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') - end - - it_behaves_like 'RESTful project resources' do - let(:actions) { [:index, :create, :destroy] } - let(:controller) { 'hooks' } - end -end - -# project_commit GET /:project_id/commit/:id(.:format) commit#show {id: /[[:alnum:]]{6,40}/, project_id: /[^\/]+/} -describe Projects::CommitController, 'routing' do - it 'to #show' do - expect(get('/gitlab/gitlabhq/commit/4246fb')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fb') - expect(get('/gitlab/gitlabhq/commit/4246fb.diff')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fb', format: 'diff') - expect(get('/gitlab/gitlabhq/commit/4246fb.patch')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fb', format: 'patch') - expect(get('/gitlab/gitlabhq/commit/4246fbd13872934f72a8fd0d6fb1317b47b59cb5')).to route_to('projects/commit#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '4246fbd13872934f72a8fd0d6fb1317b47b59cb5') - end -end - -# patch_project_commit GET /:project_id/commits/:id/patch(.:format) commits#patch -# project_commits GET /:project_id/commits(.:format) commits#index -# POST /:project_id/commits(.:format) commits#create -# project_commit GET /:project_id/commits/:id(.:format) commits#show -describe Projects::CommitsController, 'routing' do - it_behaves_like 'RESTful project resources' do - let(:actions) { [:show] } - let(:controller) { 'commits' } - end - - it 'to #show' do - expect(get('/gitlab/gitlabhq/commits/master.atom')).to route_to('projects/commits#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'atom') - end -end - -# project_project_members GET /:project_id/project_members(.:format) project_members#index -# POST /:project_id/project_members(.:format) project_members#create -# PUT /:project_id/project_members/:id(.:format) project_members#update -# DELETE /:project_id/project_members/:id(.:format) project_members#destroy -describe Projects::ProjectMembersController, 'routing' do - it_behaves_like 'RESTful project resources' do - let(:actions) { [:index, :create, :update, :destroy] } - let(:controller) { 'project_members' } - end -end - -# project_milestones GET /:project_id/milestones(.:format) milestones#index -# POST /:project_id/milestones(.:format) milestones#create -# new_project_milestone GET /:project_id/milestones/new(.:format) milestones#new -# edit_project_milestone GET /:project_id/milestones/:id/edit(.:format) milestones#edit -# project_milestone GET /:project_id/milestones/:id(.:format) milestones#show -# PUT /:project_id/milestones/:id(.:format) milestones#update -# DELETE /:project_id/milestones/:id(.:format) milestones#destroy -describe Projects::MilestonesController, 'routing' do - it_behaves_like 'RESTful project resources' do - let(:controller) { 'milestones' } - let(:actions) { [:index, :create, :new, :edit, :show, :update] } - end -end - -# project_labels GET /:project_id/labels(.:format) labels#index -describe Projects::LabelsController, 'routing' do - it 'to #index' do - expect(get('/gitlab/gitlabhq/labels')).to route_to('projects/labels#index', namespace_id: 'gitlab', project_id: 'gitlabhq') - end -end - -# sort_project_issues POST /:project_id/issues/sort(.:format) issues#sort -# bulk_update_project_issues POST /:project_id/issues/bulk_update(.:format) issues#bulk_update -# search_project_issues GET /:project_id/issues/search(.:format) issues#search -# project_issues GET /:project_id/issues(.:format) issues#index -# POST /:project_id/issues(.:format) issues#create -# new_project_issue GET /:project_id/issues/new(.:format) issues#new -# edit_project_issue GET /:project_id/issues/:id/edit(.:format) issues#edit -# project_issue GET /:project_id/issues/:id(.:format) issues#show -# PUT /:project_id/issues/:id(.:format) issues#update -# DELETE /:project_id/issues/:id(.:format) issues#destroy -describe Projects::IssuesController, 'routing' do - it 'to #bulk_update' do - expect(post('/gitlab/gitlabhq/issues/bulk_update')).to route_to('projects/issues#bulk_update', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it_behaves_like 'RESTful project resources' do - let(:controller) { 'issues' } - let(:actions) { [:index, :create, :new, :edit, :show, :update] } - end -end - -# project_notes GET /:project_id/notes(.:format) notes#index -# POST /:project_id/notes(.:format) notes#create -# project_note DELETE /:project_id/notes/:id(.:format) notes#destroy -describe Projects::NotesController, 'routing' do - it_behaves_like 'RESTful project resources' do - let(:actions) { [:index, :create, :destroy] } - let(:controller) { 'notes' } - end -end - -# project_blame GET /:project_id/blame/:id(.:format) blame#show {id: /.+/, project_id: /[^\/]+/} -describe Projects::BlameController, 'routing' do - it 'to #show' do - expect(get('/gitlab/gitlabhq/blame/master/app/models/project.rb')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb') - expect(get('/gitlab/gitlabhq/blame/master/files.scss')).to route_to('projects/blame#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss') - end -end - -# project_blob GET /:project_id/blob/:id(.:format) blob#show {id: /.+/, project_id: /[^\/]+/} -describe Projects::BlobController, 'routing' do - it 'to #show' do - expect(get('/gitlab/gitlabhq/blob/master/app/models/project.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb') - expect(get('/gitlab/gitlabhq/blob/master/app/models/compare.rb')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/compare.rb') - expect(get('/gitlab/gitlabhq/blob/master/app/models/diff.js')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/diff.js') - expect(get('/gitlab/gitlabhq/blob/master/files.scss')).to route_to('projects/blob#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss') - end -end - -# project_tree GET /:project_id/tree/:id(.:format) tree#show {id: /.+/, project_id: /[^\/]+/} -describe Projects::TreeController, 'routing' do - it 'to #show' do - expect(get('/gitlab/gitlabhq/tree/master/app/models/project.rb')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/app/models/project.rb') - expect(get('/gitlab/gitlabhq/tree/master/files.scss')).to route_to('projects/tree#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/files.scss') - end -end - -describe Projects::BlobController, 'routing' do - it 'to #edit' do - expect(get('/gitlab/gitlabhq/edit/master/app/models/project.rb')).to( - route_to('projects/blob#edit', - namespace_id: 'gitlab', project_id: 'gitlabhq', - id: 'master/app/models/project.rb')) - end - - it 'to #preview' do - expect(post('/gitlab/gitlabhq/preview/master/app/models/project.rb')).to( - route_to('projects/blob#preview', - namespace_id: 'gitlab', project_id: 'gitlabhq', - id: 'master/app/models/project.rb')) - end -end - -# project_compare_index GET /:project_id/compare(.:format) compare#index {id: /[^\/]+/, project_id: /[^\/]+/} -# POST /:project_id/compare(.:format) compare#create {id: /[^\/]+/, project_id: /[^\/]+/} -# project_compare /:project_id/compare/:from...:to(.:format) compare#show {from: /.+/, to: /.+/, id: /[^\/]+/, project_id: /[^\/]+/} -describe Projects::CompareController, 'routing' do - it 'to #index' do - expect(get('/gitlab/gitlabhq/compare')).to route_to('projects/compare#index', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #compare' do - expect(post('/gitlab/gitlabhq/compare')).to route_to('projects/compare#create', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #show' do - expect(get('/gitlab/gitlabhq/compare/master...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'master', to: 'stable') - expect(get('/gitlab/gitlabhq/compare/issue/1234...stable')).to route_to('projects/compare#show', namespace_id: 'gitlab', project_id: 'gitlabhq', from: 'issue/1234', to: 'stable') - end -end - -describe Projects::NetworkController, 'routing' do - it 'to #show' do - expect(get('/gitlab/gitlabhq/network/master')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master') - expect(get('/gitlab/gitlabhq/network/master.json')).to route_to('projects/network#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json') - end -end - -describe Projects::GraphsController, 'routing' do - it 'to #show' do - expect(get('/gitlab/gitlabhq/graphs/master')).to route_to('projects/graphs#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master') - end -end - -describe Projects::ForksController, 'routing' do - it 'to #new' do - expect(get('/gitlab/gitlabhq/fork/new')).to route_to('projects/forks#new', namespace_id: 'gitlab', project_id: 'gitlabhq') - end - - it 'to #create' do - expect(post('/gitlab/gitlabhq/fork')).to route_to('projects/forks#create', namespace_id: 'gitlab', project_id: 'gitlabhq') - end -end - -# project_avatar DELETE /project/avatar(.:format) projects/avatars#destroy -describe Projects::AvatarsController, 'routing' do - it 'to #destroy' do - expect(delete('/gitlab/gitlabhq/avatar')).to route_to( - 'projects/avatars#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq') - end -end diff --git a/spec/services/archive_repository_service_spec.rb b/spec/services/archive_repository_service_spec.rb deleted file mode 100644 index f168a9139765de1383df224f2a4696582a6a76a3..0000000000000000000000000000000000000000 --- a/spec/services/archive_repository_service_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -require 'spec_helper' - -describe ArchiveRepositoryService do - let(:project) { create(:project) } - subject { ArchiveRepositoryService.new(project, "master", "zip") } - - describe "#execute" do - it "cleans old archives" do - expect(project.repository).to receive(:clean_old_archives) - - subject.execute(timeout: 0.0) - end - - context "when the repository doesn't have an archive file path" do - before do - allow(project.repository).to receive(:archive_file_path).and_return(nil) - end - - it "raises an error" do - expect { - subject.execute(timeout: 0.0) - }.to raise_error - end - end - - context "when the repository has an archive file path" do - let(:file_path) { "/archive.zip" } - let(:pid_file_path) { "/archive.zip.pid" } - - before do - allow(project.repository).to receive(:archive_file_path).and_return(file_path) - allow(project.repository).to receive(:archive_pid_file_path).and_return(pid_file_path) - end - - context "when the archive file already exists" do - before do - allow(File).to receive(:exist?).with(file_path).and_return(true) - end - - it "returns the file path" do - expect(subject.execute(timeout: 0.0)).to eq(file_path) - end - end - - context "when the archive file doesn't exist yet" do - before do - allow(File).to receive(:exist?).with(file_path).and_return(false) - allow(File).to receive(:exist?).with(pid_file_path).and_return(true) - end - - context "when the archive pid file doesn't exist yet" do - before do - allow(File).to receive(:exist?).with(pid_file_path).and_return(false) - end - - it "queues the RepositoryArchiveWorker" do - expect(RepositoryArchiveWorker).to receive(:perform_async) - - subject.execute(timeout: 0.0) - end - end - - context "when the archive pid file already exists" do - it "doesn't queue the RepositoryArchiveWorker" do - expect(RepositoryArchiveWorker).not_to receive(:perform_async) - - subject.execute(timeout: 0.0) - end - end - - context "when the archive file exists after a little while" do - before do - Thread.new do - sleep 0.1 - allow(File).to receive(:exist?).with(file_path).and_return(true) - end - end - - it "returns the file path" do - expect(subject.execute(timeout: 0.2)).to eq(file_path) - end - end - - context "when the archive file doesn't exist after the timeout" do - it "returns nil" do - expect(subject.execute(timeout: 0.0)).to eq(nil) - end - end - end - end - end -end - diff --git a/spec/services/create_snippet_service_spec.rb b/spec/services/create_snippet_service_spec.rb deleted file mode 100644 index 08689c15ca8ac937677691c73bd00bf21834ba80..0000000000000000000000000000000000000000 --- a/spec/services/create_snippet_service_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'spec_helper' - -describe CreateSnippetService do - before do - @user = create :user - @admin = create :user, admin: true - @opts = { - title: 'Test snippet', - file_name: 'snippet.rb', - content: 'puts "hello world"', - visibility_level: Gitlab::VisibilityLevel::PRIVATE - } - end - - context 'When public visibility is restricted' do - before do - allow_any_instance_of(ApplicationSetting).to( - receive(:restricted_visibility_levels).and_return( - [Gitlab::VisibilityLevel::PUBLIC] - ) - ) - - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - end - - it 'non-admins should not be able to create a public snippet' do - snippet = create_snippet(nil, @user, @opts) - expect(snippet.errors.messages).to have_key(:visibility_level) - expect(snippet.errors.messages[:visibility_level].first).to( - match('Public visibility has been restricted') - ) - end - - it 'admins should be able to create a public snippet' do - snippet = create_snippet(nil, @admin, @opts) - expect(snippet.errors.any?).to be_falsey - expect(snippet.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC) - end - end - - def create_snippet(project, user, opts) - CreateSnippetService.new(project, user, opts).execute - end -end diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb deleted file mode 100644 index 007a9eed192e2ea4c11f89a9c83caca139fe966d..0000000000000000000000000000000000000000 --- a/spec/services/event_create_service_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'spec_helper' - -describe EventCreateService do - let(:service) { EventCreateService.new } - - describe 'Issues' do - describe :open_issue do - let(:issue) { create(:issue) } - - it { expect(service.open_issue(issue, issue.author)).to be_truthy } - - it "should create new event" do - expect { service.open_issue(issue, issue.author) }.to change { Event.count } - end - end - - describe :close_issue do - let(:issue) { create(:issue) } - - it { expect(service.close_issue(issue, issue.author)).to be_truthy } - - it "should create new event" do - expect { service.close_issue(issue, issue.author) }.to change { Event.count } - end - end - - describe :reopen_issue do - let(:issue) { create(:issue) } - - it { expect(service.reopen_issue(issue, issue.author)).to be_truthy } - - it "should create new event" do - expect { service.reopen_issue(issue, issue.author) }.to change { Event.count } - end - end - end - - describe 'Merge Requests' do - describe :open_mr do - let(:merge_request) { create(:merge_request) } - - it { expect(service.open_mr(merge_request, merge_request.author)).to be_truthy } - - it "should create new event" do - expect { service.open_mr(merge_request, merge_request.author) }.to change { Event.count } - end - end - - describe :close_mr do - let(:merge_request) { create(:merge_request) } - - it { expect(service.close_mr(merge_request, merge_request.author)).to be_truthy } - - it "should create new event" do - expect { service.close_mr(merge_request, merge_request.author) }.to change { Event.count } - end - end - - describe :merge_mr do - let(:merge_request) { create(:merge_request) } - - it { expect(service.merge_mr(merge_request, merge_request.author)).to be_truthy } - - it "should create new event" do - expect { service.merge_mr(merge_request, merge_request.author) }.to change { Event.count } - end - end - - describe :reopen_mr do - let(:merge_request) { create(:merge_request) } - - it { expect(service.reopen_mr(merge_request, merge_request.author)).to be_truthy } - - it "should create new event" do - expect { service.reopen_mr(merge_request, merge_request.author) }.to change { Event.count } - end - end - end - - describe 'Milestone' do - let(:user) { create :user } - - describe :open_milestone do - let(:milestone) { create(:milestone) } - - it { expect(service.open_milestone(milestone, user)).to be_truthy } - - it "should create new event" do - expect { service.open_milestone(milestone, user) }.to change { Event.count } - end - end - - describe :close_mr do - let(:milestone) { create(:milestone) } - - it { expect(service.close_milestone(milestone, user)).to be_truthy } - - it "should create new event" do - expect { service.close_milestone(milestone, user) }.to change { Event.count } - end - end - end -end diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb deleted file mode 100644 index aa9b15dd9ecc1855b112ccb4274964b44c0e3837..0000000000000000000000000000000000000000 --- a/spec/services/git_push_service_spec.rb +++ /dev/null @@ -1,238 +0,0 @@ -require 'spec_helper' - -describe GitPushService do - include RepoHelpers - - let (:user) { create :user } - let (:project) { create :project } - let (:service) { GitPushService.new } - - before do - @blankrev = Gitlab::Git::BLANK_SHA - @oldrev = sample_commit.parent_id - @newrev = sample_commit.id - @ref = 'refs/heads/master' - end - - describe 'Push branches' do - context 'new branch' do - subject do - service.execute(project, user, @blankrev, @newrev, @ref) - end - - it { is_expected.to be_truthy } - end - - context 'existing branch' do - subject do - service.execute(project, user, @oldrev, @newrev, @ref) - end - - it { is_expected.to be_truthy } - end - - context 'rm branch' do - subject do - service.execute(project, user, @oldrev, @blankrev, @ref) - end - - it { is_expected.to be_truthy } - end - end - - describe "Git Push Data" do - before do - service.execute(project, user, @oldrev, @newrev, @ref) - @push_data = service.push_data - @commit = project.repository.commit(@newrev) - end - - subject { @push_data } - - it { is_expected.to include(object_kind: 'push') } - it { is_expected.to include(before: @oldrev) } - it { is_expected.to include(after: @newrev) } - it { is_expected.to include(ref: @ref) } - it { is_expected.to include(user_id: user.id) } - it { is_expected.to include(user_name: user.name) } - it { is_expected.to include(project_id: project.id) } - - context "with repository data" do - subject { @push_data[:repository] } - - it { is_expected.to include(name: project.name) } - it { is_expected.to include(url: project.url_to_repo) } - it { is_expected.to include(description: project.description) } - it { is_expected.to include(homepage: project.web_url) } - end - - context "with commits" do - subject { @push_data[:commits] } - - it { is_expected.to be_an(Array) } - it 'has 1 element' do - expect(subject.size).to eq(1) - end - - context "the commit" do - subject { @push_data[:commits].first } - - it { is_expected.to include(id: @commit.id) } - it { is_expected.to include(message: @commit.safe_message) } - it { is_expected.to include(timestamp: @commit.date.xmlschema) } - it do - is_expected.to include( - url: [ - Gitlab.config.gitlab.url, - project.namespace.to_param, - project.to_param, - 'commit', - @commit.id - ].join('/') - ) - end - - context "with a author" do - subject { @push_data[:commits].first[:author] } - - it { is_expected.to include(name: @commit.author_name) } - it { is_expected.to include(email: @commit.author_email) } - end - end - end - end - - describe "Push Event" do - before do - service.execute(project, user, @oldrev, @newrev, @ref) - @event = Event.last - end - - it { expect(@event).not_to be_nil } - it { expect(@event.project).to eq(project) } - it { expect(@event.action).to eq(Event::PUSHED) } - it { expect(@event.data).to eq(service.push_data) } - end - - describe "Web Hooks" do - context "execute web hooks" do - it "when pushing a branch for the first time" do - expect(project).to receive(:execute_hooks) - expect(project.default_branch).to eq("master") - expect(project.protected_branches).to receive(:create).with({ name: "master", developers_can_push: false }) - service.execute(project, user, @blankrev, 'newrev', 'refs/heads/master') - end - - it "when pushing a branch for the first time with default branch protection disabled" do - ApplicationSetting.any_instance.stub(default_branch_protection: 0) - - expect(project).to receive(:execute_hooks) - expect(project.default_branch).to eq("master") - expect(project.protected_branches).not_to receive(:create) - service.execute(project, user, @blankrev, 'newrev', 'refs/heads/master') - end - - it "when pushing a branch for the first time with default branch protection set to 'developers can push'" do - ApplicationSetting.any_instance.stub(default_branch_protection: 1) - - expect(project).to receive(:execute_hooks) - expect(project.default_branch).to eq("master") - expect(project.protected_branches).to receive(:create).with({ name: "master", developers_can_push: true }) - service.execute(project, user, @blankrev, 'newrev', 'refs/heads/master') - end - - it "when pushing new commits to existing branch" do - expect(project).to receive(:execute_hooks) - service.execute(project, user, 'oldrev', 'newrev', 'refs/heads/master') - end - end - end - - describe "cross-reference notes" do - let(:issue) { create :issue, project: project } - let(:commit_author) { create :user } - let(:commit) { project.repository.commit } - - before do - commit.stub({ - safe_message: "this commit \n mentions ##{issue.id}", - references: [issue], - author_name: commit_author.name, - author_email: commit_author.email - }) - project.repository.stub(commits_between: [commit]) - end - - it "creates a note if a pushed commit mentions an issue" do - expect(Note).to receive(:create_cross_reference_note).with(issue, commit, commit_author, project) - - service.execute(project, user, @oldrev, @newrev, @ref) - end - - it "only creates a cross-reference note if one doesn't already exist" do - Note.create_cross_reference_note(issue, commit, user, project) - - expect(Note).not_to receive(:create_cross_reference_note).with(issue, commit, commit_author, project) - - service.execute(project, user, @oldrev, @newrev, @ref) - end - - it "defaults to the pushing user if the commit's author is not known" do - commit.stub(author_name: 'unknown name', author_email: 'unknown@email.com') - expect(Note).to receive(:create_cross_reference_note).with(issue, commit, user, project) - - service.execute(project, user, @oldrev, @newrev, @ref) - end - - it "finds references in the first push to a non-default branch" do - allow(project.repository).to receive(:commits_between).with(@blankrev, @newrev).and_return([]) - allow(project.repository).to receive(:commits_between).with("master", @newrev).and_return([commit]) - - expect(Note).to receive(:create_cross_reference_note).with(issue, commit, commit_author, project) - - service.execute(project, user, @blankrev, @newrev, 'refs/heads/other') - end - end - - describe "closing issues from pushed commits" do - let(:issue) { create :issue, project: project } - let(:other_issue) { create :issue, project: project } - let(:commit_author) { create :user } - let(:closing_commit) { project.repository.commit } - - before do - closing_commit.stub({ - issue_closing_regex: /^([Cc]loses|[Ff]ixes) #\d+/, - safe_message: "this is some work.\n\ncloses ##{issue.iid}", - author_name: commit_author.name, - author_email: commit_author.email - }) - - project.repository.stub(commits_between: [closing_commit]) - end - - it "closes issues with commit messages" do - service.execute(project, user, @oldrev, @newrev, @ref) - - expect(Issue.find(issue.id)).to be_closed - end - - it "doesn't create cross-reference notes for a closing reference" do - expect { - service.execute(project, user, @oldrev, @newrev, @ref) - }.not_to change { Note.where(project_id: project.id, system: true, commit_id: closing_commit.id).count } - end - - it "doesn't close issues when pushed to non-default branches" do - project.stub(default_branch: 'durf') - - # The push still shouldn't create cross-reference notes. - expect { - service.execute(project, user, @oldrev, @newrev, 'refs/heads/hurf') - }.not_to change { Note.where(project_id: project.id, system: true).count } - - expect(Issue.find(issue.id)).to be_opened - end - end -end - diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb deleted file mode 100644 index a050fdf6c0eb1ac58e08a7243c49d2c76c45db22..0000000000000000000000000000000000000000 --- a/spec/services/git_tag_push_service_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'spec_helper' - -describe GitTagPushService do - include RepoHelpers - - let (:user) { create :user } - let (:project) { create :project } - let (:service) { GitTagPushService.new } - - before do - @oldrev = Gitlab::Git::BLANK_SHA - @newrev = "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b" # gitlab-test: git rev-parse refs/tags/v1.1.0 - @ref = 'refs/tags/v1.1.0' - end - - describe "Git Tag Push Data" do - before do - service.execute(project, user, @oldrev, @newrev, @ref) - @push_data = service.push_data - @tag_name = Gitlab::Git.ref_name(@ref) - @tag = project.repository.find_tag(@tag_name) - @commit = project.repository.commit(@tag.target) - end - - subject { @push_data } - - it { is_expected.to include(object_kind: 'tag_push') } - it { is_expected.to include(ref: @ref) } - it { is_expected.to include(before: @oldrev) } - it { is_expected.to include(after: @newrev) } - it { is_expected.to include(message: @tag.message) } - it { is_expected.to include(user_id: user.id) } - it { is_expected.to include(user_name: user.name) } - it { is_expected.to include(project_id: project.id) } - - context "with repository data" do - subject { @push_data[:repository] } - - it { is_expected.to include(name: project.name) } - it { is_expected.to include(url: project.url_to_repo) } - it { is_expected.to include(description: project.description) } - it { is_expected.to include(homepage: project.web_url) } - end - - context "with commits" do - subject { @push_data[:commits] } - - it { is_expected.to be_an(Array) } - it 'has 1 element' do - expect(subject.size).to eq(1) - end - - context "the commit" do - subject { @push_data[:commits].first } - - it { is_expected.to include(id: @commit.id) } - it { is_expected.to include(message: @commit.safe_message) } - it { is_expected.to include(timestamp: @commit.date.xmlschema) } - it do - is_expected.to include( - url: [ - Gitlab.config.gitlab.url, - project.namespace.to_param, - project.to_param, - 'commit', - @commit.id - ].join('/') - ) - end - - context "with a author" do - subject { @push_data[:commits].first[:author] } - - it { is_expected.to include(name: @commit.author_name) } - it { is_expected.to include(email: @commit.author_email) } - end - end - end - end - - describe "Web Hooks" do - context "execute web hooks" do - it "when pushing tags" do - expect(project).to receive(:execute_hooks) - service.execute(project, user, 'oldrev', 'newrev', 'refs/tags/v1.0.0') - end - end - end -end diff --git a/spec/services/issues/bulk_update_service_spec.rb b/spec/services/issues/bulk_update_service_spec.rb deleted file mode 100644 index a97c55011c91e8a4db4839a925f618eb6143af0f..0000000000000000000000000000000000000000 --- a/spec/services/issues/bulk_update_service_spec.rb +++ /dev/null @@ -1,121 +0,0 @@ -require 'spec_helper' - -describe Issues::BulkUpdateService do - let(:issue) { - create(:issue, project: @project) - } - - before do - @user = create :user - opts = { - name: "GitLab", - namespace: @user.namespace - } - @project = Projects::CreateService.new(@user, opts).execute - end - - describe :close_issue do - - before do - @issues = 5.times.collect do - create(:issue, project: @project) - end - @params = { - state_event: 'close', - issues_ids: @issues.map(&:id) - } - end - - it { - result = Issues::BulkUpdateService.new(@project, @user, @params).execute - expect(result[:success]).to be_truthy - expect(result[:count]).to eq(@issues.count) - - expect(@project.issues.opened).to be_empty - expect(@project.issues.closed).not_to be_empty - } - - end - - describe :reopen_issues do - - before do - @issues = 5.times.collect do - create(:closed_issue, project: @project) - end - @params = { - state_event: 'reopen', - issues_ids: @issues.map(&:id) - } - end - - it { - result = Issues::BulkUpdateService.new(@project, @user, @params).execute - expect(result[:success]).to be_truthy - expect(result[:count]).to eq(@issues.count) - - expect(@project.issues.closed).to be_empty - expect(@project.issues.opened).not_to be_empty - } - - end - - describe :update_assignee do - - before do - @new_assignee = create :user - @params = { - issues_ids: [issue.id], - assignee_id: @new_assignee.id - } - end - - it { - result = Issues::BulkUpdateService.new(@project, @user, @params).execute - expect(result[:success]).to be_truthy - expect(result[:count]).to eq(1) - - expect(@project.issues.first.assignee).to eq(@new_assignee) - } - - it 'allows mass-unassigning' do - @project.issues.first.update_attribute(:assignee, @new_assignee) - expect(@project.issues.first.assignee).not_to be_nil - - @params[:assignee_id] = -1 - - Issues::BulkUpdateService.new(@project, @user, @params).execute - expect(@project.issues.first.assignee).to be_nil - end - - it 'does not unassign when assignee_id is not present' do - @project.issues.first.update_attribute(:assignee, @new_assignee) - expect(@project.issues.first.assignee).not_to be_nil - - @params[:assignee_id] = '' - - Issues::BulkUpdateService.new(@project, @user, @params).execute - expect(@project.issues.first.assignee).not_to be_nil - end - end - - describe :update_milestone do - - before do - @milestone = create :milestone - @params = { - issues_ids: [issue.id], - milestone_id: @milestone.id - } - end - - it { - result = Issues::BulkUpdateService.new(@project, @user, @params).execute - expect(result[:success]).to be_truthy - expect(result[:count]).to eq(1) - - expect(@project.issues.first.milestone).to eq(@milestone) - } - end - -end diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb deleted file mode 100644 index d15dff1b52b24e1f17f8084d238b8151316eaacc..0000000000000000000000000000000000000000 --- a/spec/services/issues/close_service_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -require 'spec_helper' - -describe Issues::CloseService do - let(:project) { create(:empty_project) } - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:issue) { create(:issue, assignee: user2) } - - before do - project.team << [user, :master] - project.team << [user2, :developer] - end - - describe :execute do - context "valid params" do - before do - @issue = Issues::CloseService.new(project, user, {}).execute(issue) - end - - it { expect(@issue).to be_valid } - it { expect(@issue).to be_closed } - - it 'should send email to user2 about assign of new issue' do - email = ActionMailer::Base.deliveries.last - expect(email.to.first).to eq(user2.email) - expect(email.subject).to include(issue.title) - end - - it 'should create system note about issue reassign' do - note = @issue.notes.last - expect(note.note).to include "Status changed to closed" - end - end - end -end diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb deleted file mode 100644 index 7f1ebcb319897ce69b965524670ddadbc385666d..0000000000000000000000000000000000000000 --- a/spec/services/issues/create_service_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -require 'spec_helper' - -describe Issues::CreateService do - let(:project) { create(:empty_project) } - let(:user) { create(:user) } - - describe :execute do - context "valid params" do - before do - project.team << [user, :master] - opts = { - title: 'Awesome issue', - description: 'please fix' - } - - @issue = Issues::CreateService.new(project, user, opts).execute - end - - it { expect(@issue).to be_valid } - it { expect(@issue.title).to eq('Awesome issue') } - end - end -end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb deleted file mode 100644 index 22b89bec96d0e032ecf6bdc6e0a404186fe7c008..0000000000000000000000000000000000000000 --- a/spec/services/issues/update_service_spec.rb +++ /dev/null @@ -1,54 +0,0 @@ -require 'spec_helper' - -describe Issues::UpdateService do - let(:project) { create(:empty_project) } - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:issue) { create(:issue) } - let(:label) { create(:label) } - - before do - project.team << [user, :master] - project.team << [user2, :developer] - end - - describe :execute do - context "valid params" do - before do - opts = { - title: 'New title', - description: 'Also please fix', - assignee_id: user2.id, - state_event: 'close', - label_ids: [label.id] - } - - @issue = Issues::UpdateService.new(project, user, opts).execute(issue) - @issue.reload - end - - it { expect(@issue).to be_valid } - it { expect(@issue.title).to eq('New title') } - it { expect(@issue.assignee).to eq(user2) } - it { expect(@issue).to be_closed } - it { expect(@issue.labels.count).to eq(1) } - it { expect(@issue.labels.first.title).to eq('Bug') } - - it 'should send email to user2 about assign of new issue' do - email = ActionMailer::Base.deliveries.last - expect(email.to.first).to eq(user2.email) - expect(email.subject).to include(issue.title) - end - - it 'should create system note about issue reassign' do - note = @issue.notes.last - expect(note.note).to include "Reassigned to \@#{user2.username}" - end - - it 'should create system note about issue label edit' do - note = @issue.notes[1] - expect(note.note).to include "Added ~#{label.id} label" - end - end - end -end diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb deleted file mode 100644 index b3cbfd4b5b8d8e9074b186300d10f41191a1a2cd..0000000000000000000000000000000000000000 --- a/spec/services/merge_requests/close_service_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'spec_helper' - -describe MergeRequests::CloseService do - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:merge_request) { create(:merge_request, assignee: user2) } - let(:project) { merge_request.project } - - before do - project.team << [user, :master] - project.team << [user2, :developer] - end - - describe :execute do - context 'valid params' do - let(:service) { MergeRequests::CloseService.new(project, user, {}) } - - before do - allow(service).to receive(:execute_hooks) - - @merge_request = service.execute(merge_request) - end - - it { expect(@merge_request).to be_valid } - it { expect(@merge_request).to be_closed } - - it 'should execute hooks with close action' do - expect(service).to have_received(:execute_hooks). - with(@merge_request, 'close') - end - - it 'should send email to user2 about assign of new merge_request' do - email = ActionMailer::Base.deliveries.last - expect(email.to.first).to eq(user2.email) - expect(email.subject).to include(merge_request.title) - end - - it 'should create system note about merge_request reassign' do - note = @merge_request.notes.last - expect(note.note).to include 'Status changed to closed' - end - end - end -end diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb deleted file mode 100644 index d9bfdf643080752f3ede55ae554b7f590ba8d3c3..0000000000000000000000000000000000000000 --- a/spec/services/merge_requests/create_service_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -describe MergeRequests::CreateService do - let(:project) { create(:project) } - let(:user) { create(:user) } - - describe :execute do - context 'valid params' do - let(:opts) do - { - title: 'Awesome merge_request', - description: 'please fix', - source_branch: 'stable', - target_branch: 'master' - } - end - let(:service) { MergeRequests::CreateService.new(project, user, opts) } - - before do - project.team << [user, :master] - allow(service).to receive(:execute_hooks) - - @merge_request = service.execute - end - - it { expect(@merge_request).to be_valid } - it { expect(@merge_request.title).to eq('Awesome merge_request') } - - it 'should execute hooks with default action' do - expect(service).to have_received(:execute_hooks).with(@merge_request) - end - end - end -end diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb deleted file mode 100644 index 0a25fb12f4eaa34e964f97349fa7cb5d9ff197f3..0000000000000000000000000000000000000000 --- a/spec/services/merge_requests/merge_service_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'spec_helper' - -describe MergeRequests::MergeService do - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:merge_request) { create(:merge_request, assignee: user2) } - let(:project) { merge_request.project } - - before do - project.team << [user, :master] - project.team << [user2, :developer] - end - - describe :execute do - context 'valid params' do - let(:service) { MergeRequests::MergeService.new(project, user, {}) } - - before do - allow(service).to receive(:execute_hooks) - - service.execute(merge_request, 'Awesome message') - end - - it { expect(merge_request).to be_valid } - it { expect(merge_request).to be_merged } - - it 'should execute hooks with merge action' do - expect(service).to have_received(:execute_hooks). - with(merge_request, 'merge') - end - - it 'should send email to user2 about merge of new merge_request' do - email = ActionMailer::Base.deliveries.last - expect(email.to.first).to eq(user2.email) - expect(email.subject).to include(merge_request.title) - end - - it 'should create system note about merge_request merge' do - note = merge_request.notes.last - expect(note.note).to include 'Status changed to merged' - end - end - end -end diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb deleted file mode 100644 index 879df0c9c67655bfcf7880aab8c7e5cffe8bc0ac..0000000000000000000000000000000000000000 --- a/spec/services/merge_requests/refresh_service_spec.rb +++ /dev/null @@ -1,98 +0,0 @@ -require 'spec_helper' - -describe MergeRequests::RefreshService do - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:service) { MergeRequests::RefreshService } - - describe :execute do - before do - @user = create(:user) - group = create(:group) - group.add_owner(@user) - - @project = create(:project, namespace: group) - @fork_project = Projects::ForkService.new(@project, @user).execute - @merge_request = create(:merge_request, source_project: @project, - source_branch: 'master', - target_branch: 'feature', - target_project: @project) - - @fork_merge_request = create(:merge_request, source_project: @fork_project, - source_branch: 'master', - target_branch: 'feature', - target_project: @project) - - @commits = @merge_request.commits - - @oldrev = @commits.last.id - @newrev = @commits.first.id - end - - context 'push to origin repo source branch' do - before do - service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master') - reload_mrs - end - - it { expect(@merge_request.notes).not_to be_empty } - it { expect(@merge_request).to be_open } - it { expect(@fork_merge_request).to be_open } - it { expect(@fork_merge_request.notes).to be_empty } - end - - context 'push to origin repo target branch' do - before do - service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature') - reload_mrs - end - - it { expect(@merge_request.notes.last.note).to include('changed to merged') } - it { expect(@merge_request).to be_merged } - it { expect(@fork_merge_request).to be_merged } - it { expect(@fork_merge_request.notes.last.note).to include('changed to merged') } - end - - context 'push to fork repo source branch' do - before do - service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/master') - reload_mrs - end - - it { expect(@merge_request.notes).to be_empty } - it { expect(@merge_request).to be_open } - it { expect(@fork_merge_request.notes.last.note).to include('Added 4 commits') } - it { expect(@fork_merge_request).to be_open } - end - - context 'push to fork repo target branch' do - before do - service.new(@fork_project, @user).execute(@oldrev, @newrev, 'refs/heads/feature') - reload_mrs - end - - it { expect(@merge_request.notes).to be_empty } - it { expect(@merge_request).to be_open } - it { expect(@fork_merge_request.notes).to be_empty } - it { expect(@fork_merge_request).to be_open } - end - - context 'push to origin repo target branch after fork project was removed' do - before do - @fork_project.destroy - service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/feature') - reload_mrs - end - - it { expect(@merge_request.notes.last.note).to include('changed to merged') } - it { expect(@merge_request).to be_merged } - it { expect(@fork_merge_request).to be_open } - it { expect(@fork_merge_request.notes).to be_empty } - end - - def reload_mrs - @merge_request.reload - @fork_merge_request.reload - end - end -end diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb deleted file mode 100644 index 9401bc3b55893ab47e734083b10d2dbd6cead703..0000000000000000000000000000000000000000 --- a/spec/services/merge_requests/reopen_service_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -require 'spec_helper' - -describe MergeRequests::ReopenService do - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:merge_request) { create(:merge_request, assignee: user2) } - let(:project) { merge_request.project } - - before do - project.team << [user, :master] - project.team << [user2, :developer] - end - - describe :execute do - context 'valid params' do - let(:service) { MergeRequests::ReopenService.new(project, user, {}) } - - before do - allow(service).to receive(:execute_hooks) - - merge_request.state = :closed - service.execute(merge_request) - end - - it { expect(merge_request).to be_valid } - it { expect(merge_request).to be_reopened } - - it 'should execute hooks with reopen action' do - expect(service).to have_received(:execute_hooks). - with(merge_request, 'reopen') - end - - it 'should send email to user2 about reopen of merge_request' do - email = ActionMailer::Base.deliveries.last - expect(email.to.first).to eq(user2.email) - expect(email.subject).to include(merge_request.title) - end - - it 'should create system note about merge_request reopen' do - note = merge_request.notes.last - expect(note.note).to include 'Status changed to reopened' - end - end - end -end diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb deleted file mode 100644 index 916b01e1c45e4a84403f52626623dd529ab9837e..0000000000000000000000000000000000000000 --- a/spec/services/merge_requests/update_service_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'spec_helper' - -describe MergeRequests::UpdateService do - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:merge_request) { create(:merge_request, :simple) } - let(:project) { merge_request.project } - let(:label) { create(:label) } - - before do - project.team << [user, :master] - project.team << [user2, :developer] - end - - describe :execute do - context 'valid params' do - let(:opts) do - { - title: 'New title', - description: 'Also please fix', - assignee_id: user2.id, - state_event: 'close', - label_ids: [label.id] - } - end - - let(:service) { MergeRequests::UpdateService.new(project, user, opts) } - - before do - allow(service).to receive(:execute_hooks) - - @merge_request = service.execute(merge_request) - @merge_request.reload - end - - it { expect(@merge_request).to be_valid } - it { expect(@merge_request.title).to eq('New title') } - it { expect(@merge_request.assignee).to eq(user2) } - it { expect(@merge_request).to be_closed } - it { expect(@merge_request.labels.count).to eq(1) } - it { expect(@merge_request.labels.first.title).to eq('Bug') } - - it 'should execute hooks with update action' do - expect(service).to have_received(:execute_hooks). - with(@merge_request, 'update') - end - - it 'should send email to user2 about assign of new merge_request' do - email = ActionMailer::Base.deliveries.last - expect(email.to.first).to eq(user2.email) - expect(email.subject).to include(merge_request.title) - end - - it 'should create system note about merge_request reassign' do - note = @merge_request.notes.last - expect(note.note).to include "Reassigned to \@#{user2.username}" - end - - it 'should create system note about merge_request label edit' do - note = @merge_request.notes[1] - expect(note.note).to include "Added ~#{label.id} label" - end - end - end -end diff --git a/spec/services/milestones/group_service_spec.rb b/spec/services/milestones/group_service_spec.rb deleted file mode 100644 index 74eb0f99e0f29e713c49fd27945bf573fbf13816..0000000000000000000000000000000000000000 --- a/spec/services/milestones/group_service_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -require 'spec_helper' - -describe Milestones::GroupService do - let(:user) { create(:user) } - let(:user2) { create(:user) } - let(:group) { create(:group) } - let(:project1) { create(:project, group: group) } - let(:project2) { create(:project, path: 'gitlab-ci', group: group) } - let(:project3) { create(:project, path: 'cookbook-gitlab', group: group) } - let(:milestone1_project1) { create(:milestone, title: "Milestone v1.2", project: project1) } - let(:milestone1_project2) { create(:milestone, title: "Milestone v1.2", project: project2) } - let(:milestone1_project3) { create(:milestone, title: "Milestone v1.2", project: project3) } - let(:milestone2_project1) { create(:milestone, title: "VD-123", project: project1) } - let(:milestone2_project2) { create(:milestone, title: "VD-123", project: project2) } - let(:milestone2_project3) { create(:milestone, title: "VD-123", project: project3) } - - describe 'execute' do - context 'with valid projects' do - before do - milestones = - [ - milestone1_project1, - milestone1_project2, - milestone1_project3, - milestone2_project1, - milestone2_project2, - milestone2_project3 - ] - @group_milestones = Milestones::GroupService.new(milestones).execute - end - - it 'should have all project milestones' do - expect(@group_milestones.count).to eq(2) - end - - it 'should have all project milestones titles' do - expect(@group_milestones.map { |group_milestone| group_milestone.title }).to match_array(['Milestone v1.2', 'VD-123']) - end - - it 'should have all project milestones' do - expect(@group_milestones.map { |group_milestone| group_milestone.milestones.count }.sum).to eq(6) - end - end - end - - describe 'milestone' do - context 'with valid title' do - before do - milestones = - [ - milestone1_project1, - milestone1_project2, - milestone1_project3, - milestone2_project1, - milestone2_project2, - milestone2_project3 - ] - @group_milestones = Milestones::GroupService.new(milestones).milestone('Milestone v1.2') - end - - it 'should have exactly one group milestone' do - expect(@group_milestones.title).to eq('Milestone v1.2') - end - - it 'should have all project milestones with the same title' do - expect(@group_milestones.milestones.count).to eq(3) - end - end - end -end diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb deleted file mode 100644 index 1a02299bf19c5f4b247d134b56c589396767ca43..0000000000000000000000000000000000000000 --- a/spec/services/notes/create_service_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' - -describe Notes::CreateService do - let(:project) { create(:empty_project) } - let(:issue) { create(:issue, project: project) } - let(:user) { create(:user) } - - describe :execute do - context "valid params" do - before do - project.team << [user, :master] - opts = { - note: 'Awesome comment', - noteable_type: 'Issue', - noteable_id: issue.id - } - - @note = Notes::CreateService.new(project, user, opts).execute - end - - it { expect(@note).to be_valid } - it { expect(@note.note).to eq('Awesome comment') } - end - end -end - diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb deleted file mode 100644 index bfca2c88264354f7aca3f3abd5c06579ec18ccc0..0000000000000000000000000000000000000000 --- a/spec/services/notification_service_spec.rb +++ /dev/null @@ -1,455 +0,0 @@ -require 'spec_helper' - -describe NotificationService do - let(:notification) { NotificationService.new } - - describe 'Keys' do - describe :new_key do - let!(:key) { create(:personal_key) } - - it { expect(notification.new_key(key)).to be_truthy } - - it 'should sent email to key owner' do - expect(Notify).to receive(:new_ssh_key_email).with(key.id) - notification.new_key(key) - end - end - end - - describe 'Email' do - describe :new_email do - let!(:email) { create(:email) } - - it { expect(notification.new_email(email)).to be_truthy } - - it 'should send email to email owner' do - expect(Notify).to receive(:new_email_email).with(email.id) - notification.new_email(email) - end - end - end - - describe 'Notes' do - context 'issue note' do - let(:issue) { create(:issue, assignee: create(:user)) } - let(:mentioned_issue) { create(:issue, assignee: issue.assignee) } - let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced') } - - before do - build_team(note.project) - end - - describe :new_note do - it do - add_users_with_subscription(note.project, issue) - - should_email(@u_watcher.id) - should_email(note.noteable.author_id) - should_email(note.noteable.assignee_id) - should_email(@u_mentioned.id) - should_email(@subscriber.id) - should_not_email(note.author_id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - should_not_email(@unsubscriber.id) - - notification.new_note(note) - end - - it 'filters out "mentioned in" notes' do - mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author, issue.project) - - expect(Notify).not_to receive(:note_issue_email) - notification.new_note(mentioned_note) - end - end - - describe 'new note on issue in project that belongs to a group' do - let(:group) { create(:group) } - - before do - note.project.namespace_id = group.id - note.project.group.add_user(@u_watcher, GroupMember::MASTER) - note.project.save - user_project = note.project.project_members.find_by_user_id(@u_watcher.id) - user_project.notification_level = Notification::N_PARTICIPATING - user_project.save - group_member = note.project.group.group_members.find_by_user_id(@u_watcher.id) - group_member.notification_level = Notification::N_GLOBAL - group_member.save - end - - it do - should_email(note.noteable.author_id) - should_email(note.noteable.assignee_id) - should_email(@u_mentioned.id) - should_not_email(@u_watcher.id) - should_not_email(note.author_id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - notification.new_note(note) - end - end - - def should_email(user_id) - expect(Notify).to receive(:note_issue_email).with(user_id, note.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:note_issue_email).with(user_id, note.id) - end - end - - context 'issue note mention' do - let(:issue) { create(:issue, assignee: create(:user)) } - let(:mentioned_issue) { create(:issue, assignee: issue.assignee) } - let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@all mentioned') } - - before do - build_team(note.project) - end - - describe :new_note do - it do - # Notify all team members - note.project.team.members.each do |member| - # User with disabled notification should not be notified - next if member.id == @u_disabled.id - should_email(member.id) - end - should_email(note.noteable.author_id) - should_email(note.noteable.assignee_id) - - should_not_email(note.author_id) - should_not_email(@u_mentioned.id) - should_not_email(@u_disabled.id) - should_not_email(@u_not_mentioned.id) - notification.new_note(note) - end - - it 'filters out "mentioned in" notes' do - mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author, issue.project) - - expect(Notify).not_to receive(:note_issue_email) - notification.new_note(mentioned_note) - end - end - - def should_email(user_id) - expect(Notify).to receive(:note_issue_email).with(user_id, note.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:note_issue_email).with(user_id, note.id) - end - end - - context 'commit note' do - let(:note) { create(:note_on_commit) } - - before do - build_team(note.project) - note.stub(:commit_author => @u_committer) - end - - describe :new_note do - it do - should_email(@u_committer.id, note) - should_email(@u_watcher.id, note) - should_not_email(@u_mentioned.id, note) - should_not_email(note.author_id, note) - should_not_email(@u_participating.id, note) - should_not_email(@u_disabled.id, note) - notification.new_note(note) - end - - it do - note.update_attribute(:note, '@mention referenced') - should_email(@u_committer.id, note) - should_email(@u_watcher.id, note) - should_email(@u_mentioned.id, note) - should_not_email(note.author_id, note) - should_not_email(@u_participating.id, note) - should_not_email(@u_disabled.id, note) - notification.new_note(note) - end - - it do - @u_committer.update_attributes(notification_level: Notification::N_MENTION) - should_not_email(@u_committer.id, note) - notification.new_note(note) - end - - def should_email(user_id, n) - expect(Notify).to receive(:note_commit_email).with(user_id, n.id) - end - - def should_not_email(user_id, n) - expect(Notify).not_to receive(:note_commit_email).with(user_id, n.id) - end - end - end - end - - describe 'Issues' do - let(:issue) { create :issue, assignee: create(:user), description: 'cc @participant' } - - before do - build_team(issue.project) - add_users_with_subscription(issue.project, issue) - end - - describe :new_issue do - it do - should_email(issue.assignee_id) - should_email(@u_watcher.id) - should_email(@u_participant_mentioned.id) - should_not_email(@u_mentioned.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - notification.new_issue(issue, @u_disabled) - end - - it do - issue.assignee.update_attributes(notification_level: Notification::N_MENTION) - should_not_email(issue.assignee_id) - notification.new_issue(issue, @u_disabled) - end - - def should_email(user_id) - expect(Notify).to receive(:new_issue_email).with(user_id, issue.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:new_issue_email).with(user_id, issue.id) - end - end - - describe :reassigned_issue do - it 'should email new assignee' do - should_email(issue.assignee_id) - should_email(@u_watcher.id) - should_email(@u_participant_mentioned.id) - should_email(@subscriber.id) - should_not_email(@unsubscriber.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - - notification.reassigned_issue(issue, @u_disabled) - end - - def should_email(user_id) - expect(Notify).to receive(:reassigned_issue_email).with(user_id, issue.id, nil, @u_disabled.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:reassigned_issue_email).with(user_id, issue.id, issue.assignee_id, @u_disabled.id) - end - end - - describe :close_issue do - it 'should sent email to issue assignee and issue author' do - should_email(issue.assignee_id) - should_email(issue.author_id) - should_email(@u_watcher.id) - should_email(@u_participant_mentioned.id) - should_email(@subscriber.id) - should_not_email(@unsubscriber.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - - notification.close_issue(issue, @u_disabled) - end - - def should_email(user_id) - expect(Notify).to receive(:closed_issue_email).with(user_id, issue.id, @u_disabled.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:closed_issue_email).with(user_id, issue.id, @u_disabled.id) - end - end - - describe :reopen_issue do - it 'should send email to issue assignee and issue author' do - should_email(issue.assignee_id) - should_email(issue.author_id) - should_email(@u_watcher.id) - should_email(@u_participant_mentioned.id) - should_email(@subscriber.id) - should_not_email(@unsubscriber.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - - notification.reopen_issue(issue, @u_disabled) - end - - def should_email(user_id) - expect(Notify).to receive(:issue_status_changed_email).with(user_id, issue.id, 'reopened', @u_disabled.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:issue_status_changed_email).with(user_id, issue.id, 'reopened', @u_disabled.id) - end - end - end - - describe 'Merge Requests' do - let(:merge_request) { create :merge_request, assignee: create(:user) } - - before do - build_team(merge_request.target_project) - add_users_with_subscription(merge_request.target_project, merge_request) - end - - describe :new_merge_request do - it do - should_email(merge_request.assignee_id) - should_email(@u_watcher.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - notification.new_merge_request(merge_request, @u_disabled) - end - - def should_email(user_id) - expect(Notify).to receive(:new_merge_request_email).with(user_id, merge_request.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:new_merge_request_email).with(user_id, merge_request.id) - end - end - - describe :reassigned_merge_request do - it do - should_email(merge_request.assignee_id) - should_email(@u_watcher.id) - should_email(@subscriber.id) - should_not_email(@unsubscriber.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - notification.reassigned_merge_request(merge_request, merge_request.author) - end - - def should_email(user_id) - expect(Notify).to receive(:reassigned_merge_request_email).with(user_id, merge_request.id, nil, merge_request.author_id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:reassigned_merge_request_email).with(user_id, merge_request.id, merge_request.assignee_id, merge_request.author_id) - end - end - - describe :closed_merge_request do - it do - should_email(merge_request.assignee_id) - should_email(@u_watcher.id) - should_email(@subscriber.id) - should_not_email(@unsubscriber.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - notification.close_mr(merge_request, @u_disabled) - end - - def should_email(user_id) - expect(Notify).to receive(:closed_merge_request_email).with(user_id, merge_request.id, @u_disabled.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:closed_merge_request_email).with(user_id, merge_request.id, @u_disabled.id) - end - end - - describe :merged_merge_request do - it do - should_email(merge_request.assignee_id) - should_email(@u_watcher.id) - should_email(@subscriber.id) - should_not_email(@unsubscriber.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - notification.merge_mr(merge_request, @u_disabled) - end - - def should_email(user_id) - expect(Notify).to receive(:merged_merge_request_email).with(user_id, merge_request.id, @u_disabled.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:merged_merge_request_email).with(user_id, merge_request.id, @u_disabled.id) - end - end - - describe :reopen_merge_request do - it do - should_email(merge_request.assignee_id) - should_email(@u_watcher.id) - should_email(@subscriber.id) - should_not_email(@unsubscriber.id) - should_not_email(@u_participating.id) - should_not_email(@u_disabled.id) - notification.reopen_mr(merge_request, @u_disabled) - end - - def should_email(user_id) - expect(Notify).to receive(:merge_request_status_email).with(user_id, merge_request.id, 'reopened', @u_disabled.id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:merge_request_status_email).with(user_id, merge_request.id, 'reopened', @u_disabled.id) - end - end - end - - describe 'Projects' do - let(:project) { create :project } - - before do - build_team(project) - end - - describe :project_was_moved do - it do - should_email(@u_watcher.id) - should_email(@u_participating.id) - should_not_email(@u_disabled.id) - notification.project_was_moved(project) - end - - def should_email(user_id) - expect(Notify).to receive(:project_was_moved_email).with(project.id, user_id) - end - - def should_not_email(user_id) - expect(Notify).not_to receive(:project_was_moved_email).with(project.id, user_id) - end - end - end - - def build_team(project) - @u_watcher = create(:user, notification_level: Notification::N_WATCH) - @u_participating = create(:user, notification_level: Notification::N_PARTICIPATING) - @u_participant_mentioned = create(:user, username: 'participant', notification_level: Notification::N_PARTICIPATING) - @u_disabled = create(:user, notification_level: Notification::N_DISABLED) - @u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_MENTION) - @u_committer = create(:user, username: 'committer') - @u_not_mentioned = create(:user, username: 'regular', notification_level: Notification::N_PARTICIPATING) - - project.team << [@u_watcher, :master] - project.team << [@u_participating, :master] - project.team << [@u_disabled, :master] - project.team << [@u_mentioned, :master] - project.team << [@u_committer, :master] - end - - def add_users_with_subscription(project, issuable) - @subscriber = create :user - @unsubscriber = create :user - - project.team << [@subscriber, :master] - project.team << [@unsubscriber, :master] - - issuable.subscriptions.create(user: @subscriber, subscribed: true) - issuable.subscriptions.create(user: @unsubscriber, subscribed: false) - end -end diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb deleted file mode 100644 index 337dae592dd488024653093b2c918ec94880c2bc..0000000000000000000000000000000000000000 --- a/spec/services/projects/create_service_spec.rb +++ /dev/null @@ -1,90 +0,0 @@ -require 'spec_helper' - -describe Projects::CreateService do - describe :create_by_user do - before do - @user = create :user - @admin = create :user, admin: true - @opts = { - name: "GitLab", - namespace: @user.namespace - } - end - - context 'user namespace' do - before do - @project = create_project(@user, @opts) - end - - it { expect(@project).to be_valid } - it { expect(@project.owner).to eq(@user) } - it { expect(@project.namespace).to eq(@user.namespace) } - end - - context 'group namespace' do - before do - @group = create :group - @group.add_owner(@user) - - @opts.merge!(namespace_id: @group.id) - @project = create_project(@user, @opts) - end - - it { expect(@project).to be_valid } - it { expect(@project.owner).to eq(@group) } - it { expect(@project.namespace).to eq(@group) } - end - - context 'wiki_enabled creates repository directory' do - context 'wiki_enabled true creates wiki repository directory' do - before do - @project = create_project(@user, @opts) - @path = ProjectWiki.new(@project, @user).send(:path_to_repo) - end - - it { expect(File.exists?(@path)).to be_truthy } - end - - context 'wiki_enabled false does not create wiki repository directory' do - before do - @opts.merge!(wiki_enabled: false) - @project = create_project(@user, @opts) - @path = ProjectWiki.new(@project, @user).send(:path_to_repo) - end - - it { expect(File.exists?(@path)).to be_falsey } - end - end - - context 'restricted visibility level' do - before do - allow_any_instance_of(ApplicationSetting).to( - receive(:restricted_visibility_levels).and_return([20]) - ) - - @opts.merge!( - visibility_level: Gitlab::VisibilityLevel.options['Public'] - ) - end - - it 'should not allow a restricted visibility level for non-admins' do - project = create_project(@user, @opts) - expect(project).to respond_to(:errors) - expect(project.errors.messages).to have_key(:visibility_level) - expect(project.errors.messages[:visibility_level].first).to( - match('restricted by your GitLab administrator') - ) - end - - it 'should allow a restricted visibility level for admins' do - project = create_project(@admin, @opts) - expect(project.errors.any?).to be(false) - expect(project.saved?).to be(true) - end - end - end - - def create_project(user, opts) - Projects::CreateService.new(user, opts).execute - end -end diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb deleted file mode 100644 index c9025bdf133087619ec0999f79e543db7d51b97e..0000000000000000000000000000000000000000 --- a/spec/services/projects/fork_service_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -require 'spec_helper' - -describe Projects::ForkService do - describe :fork_by_user do - before do - @from_namespace = create(:namespace) - @from_user = create(:user, namespace: @from_namespace ) - @from_project = create(:project, creator_id: @from_user.id, - namespace: @from_namespace, star_count: 107, - description: 'wow such project') - @to_namespace = create(:namespace) - @to_user = create(:user, namespace: @to_namespace) - end - - context 'fork project' do - describe "successfully creates project in the user namespace" do - let(:to_project) { fork_project(@from_project, @to_user) } - - it { expect(to_project.owner).to eq(@to_user) } - it { expect(to_project.namespace).to eq(@to_user.namespace) } - it { expect(to_project.star_count).to be_zero } - it { expect(to_project.description).to eq(@from_project.description) } - end - end - - context 'fork project failure' do - it "fails due to transaction failure" do - @to_project = fork_project(@from_project, @to_user, false) - expect(@to_project.errors).not_to be_empty - expect(@to_project.errors[:base]).to include("Fork transaction failed.") - end - end - - context 'project already exists' do - it "should fail due to validation, not transaction failure" do - @existing_project = create(:project, creator_id: @to_user.id, name: @from_project.name, namespace: @to_namespace) - @to_project = fork_project(@from_project, @to_user) - expect(@existing_project.persisted?).to be_truthy - expect(@to_project.errors[:base]).to include("Invalid fork destination") - expect(@to_project.errors[:base]).not_to include("Fork transaction failed.") - end - end - - context 'GitLab CI is enabled' do - it "calls fork registrator for CI" do - @from_project.build_missing_services - @from_project.gitlab_ci_service.update_attributes(active: true) - - expect(ForkRegistrationWorker).to receive(:perform_async) - - fork_project(@from_project, @to_user) - end - end - end - - describe :fork_to_namespace do - before do - @group_owner = create(:user) - @developer = create(:user) - @project = create(:project, creator_id: @group_owner.id, - star_count: 777, - description: 'Wow, such a cool project!') - @group = create(:group) - @group.add_user(@group_owner, GroupMember::OWNER) - @group.add_user(@developer, GroupMember::DEVELOPER) - @opts = { namespace: @group } - end - - context 'fork project for group' do - it 'group owner successfully forks project into the group' do - to_project = fork_project(@project, @group_owner, true, @opts) - expect(to_project.owner).to eq(@group) - expect(to_project.namespace).to eq(@group) - expect(to_project.name).to eq(@project.name) - expect(to_project.path).to eq(@project.path) - expect(to_project.description).to eq(@project.description) - expect(to_project.star_count).to be_zero - end - end - - context 'fork project for group when user not owner' do - it 'group developer should fail to fork project into the group' do - to_project = fork_project(@project, @developer, true, @opts) - expect(to_project.errors[:namespace]).to eq(['insufficient access rights']) - end - end - - context 'project already exists in group' do - it 'should fail due to validation, not transaction failure' do - existing_project = create(:project, name: @project.name, - namespace: @group) - to_project = fork_project(@project, @group_owner, true, @opts) - expect(existing_project.persisted?).to be_truthy - expect(to_project.errors[:base]).to eq(['Invalid fork destination']) - expect(to_project.errors[:name]).to eq(['has already been taken']) - expect(to_project.errors[:path]).to eq(['has already been taken']) - end - end - end - - def fork_project(from_project, user, fork_success = true, params = {}) - context = Projects::ForkService.new(from_project, user, params) - shell = double('gitlab_shell') - shell.stub(fork_repository: fork_success) - context.stub(gitlab_shell: shell) - context.execute - end -end diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb deleted file mode 100644 index 5650626fb18428cc082776a9bbb6169da491ebfb..0000000000000000000000000000000000000000 --- a/spec/services/projects/transfer_service_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'spec_helper' - -describe Projects::TransferService do - let(:user) { create(:user) } - let(:group) { create(:group) } - let(:project) { create(:project, namespace: user.namespace) } - - context 'namespace -> namespace' do - before do - group.add_owner(user) - @result = transfer_project(project, user, new_namespace_id: group.id) - end - - it { expect(@result).to be_truthy } - it { expect(project.namespace).to eq(group) } - end - - context 'namespace -> no namespace' do - before do - @result = transfer_project(project, user, new_namespace_id: nil) - end - - it { expect(@result).not_to be_nil } # { result.should be_false } passes on nil - it { expect(@result).to be_falsey } - it { expect(project.namespace).to eq(user.namespace) } - end - - context 'namespace -> not allowed namespace' do - before do - @result = transfer_project(project, user, new_namespace_id: group.id) - end - - it { expect(@result).not_to be_nil } # { result.should be_false } passes on nil - it { expect(@result).to be_falsey } - it { expect(project.namespace).to eq(user.namespace) } - end - - def transfer_project(project, user, params) - Projects::TransferService.new(project, user, params).execute - end -end diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb deleted file mode 100644 index ea5b8813105ca7f1a7b6f4585e2ebb2c8a341ac3..0000000000000000000000000000000000000000 --- a/spec/services/projects/update_service_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -require 'spec_helper' - -describe Projects::UpdateService do - describe :update_by_user do - before do - @user = create :user - @admin = create :user, admin: true - @project = create :project, creator_id: @user.id, namespace: @user.namespace - @opts = {} - end - - context 'should be private when updated to private' do - before do - @created_private = @project.private? - - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) - update_project(@project, @user, @opts) - end - - it { expect(@created_private).to be_truthy } - it { expect(@project.private?).to be_truthy } - end - - context 'should be internal when updated to internal' do - before do - @created_private = @project.private? - - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - update_project(@project, @user, @opts) - end - - it { expect(@created_private).to be_truthy } - it { expect(@project.internal?).to be_truthy } - end - - context 'should be public when updated to public' do - before do - @created_private = @project.private? - - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - update_project(@project, @user, @opts) - end - - it { expect(@created_private).to be_truthy } - it { expect(@project.public?).to be_truthy } - end - - context 'respect configured visibility restrictions setting' do - before(:each) do - allow_any_instance_of(ApplicationSetting).to( - receive(:restricted_visibility_levels).and_return([20]) - ) - end - - context 'should be private when updated to private' do - before do - @created_private = @project.private? - - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) - update_project(@project, @user, @opts) - end - - it { expect(@created_private).to be_truthy } - it { expect(@project.private?).to be_truthy } - end - - context 'should be internal when updated to internal' do - before do - @created_private = @project.private? - - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::INTERNAL) - update_project(@project, @user, @opts) - end - - it { expect(@created_private).to be_truthy } - it { expect(@project.internal?).to be_truthy } - end - - context 'should be private when updated to public' do - before do - @created_private = @project.private? - - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - update_project(@project, @user, @opts) - end - - it { expect(@created_private).to be_truthy } - it { expect(@project.private?).to be_truthy } - end - - context 'should be public when updated to public by admin' do - before do - @created_private = @project.private? - - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - update_project(@project, @admin, @opts) - end - - it { expect(@created_private).to be_truthy } - it { expect(@project.public?).to be_truthy } - end - end - end - - def update_project(project, user, opts) - Projects::UpdateService.new(project, user, opts).execute - end -end diff --git a/spec/services/projects/upload_service_spec.rb b/spec/services/projects/upload_service_spec.rb deleted file mode 100644 index e5c47015a033c096d406bfe82fb1d6db5418a6c9..0000000000000000000000000000000000000000 --- a/spec/services/projects/upload_service_spec.rb +++ /dev/null @@ -1,85 +0,0 @@ -require 'spec_helper' - -describe Projects::UploadService do - describe 'File service' do - before do - @user = create :user - @project = create :project, creator_id: @user.id, namespace: @user.namespace - end - - context 'for valid gif file' do - before do - gif = fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') - @link_to_file = upload_file(@project.repository, gif) - end - - it { expect(@link_to_file).to have_key('alt') } - it { expect(@link_to_file).to have_key('url') } - it { expect(@link_to_file).to have_key('is_image') } - it { expect(@link_to_file).to have_value('banana_sample') } - it { expect(@link_to_file['is_image']).to equal(true) } - it { expect(@link_to_file['url']).to match("/#{@project.path_with_namespace}") } - it { expect(@link_to_file['url']).to match('banana_sample.gif') } - end - - context 'for valid png file' do - before do - png = fixture_file_upload(Rails.root + 'spec/fixtures/dk.png', - 'image/png') - @link_to_file = upload_file(@project.repository, png) - end - - it { expect(@link_to_file).to have_key('alt') } - it { expect(@link_to_file).to have_key('url') } - it { expect(@link_to_file).to have_value('dk') } - it { expect(@link_to_file).to have_key('is_image') } - it { expect(@link_to_file['is_image']).to equal(true) } - it { expect(@link_to_file['url']).to match("/#{@project.path_with_namespace}") } - it { expect(@link_to_file['url']).to match('dk.png') } - end - - context 'for valid jpg file' do - before do - jpg = fixture_file_upload(Rails.root + 'spec/fixtures/rails_sample.jpg', 'image/jpg') - @link_to_file = upload_file(@project.repository, jpg) - end - - it { expect(@link_to_file).to have_key('alt') } - it { expect(@link_to_file).to have_key('url') } - it { expect(@link_to_file).to have_key('is_image') } - it { expect(@link_to_file).to have_value('rails_sample') } - it { expect(@link_to_file['is_image']).to equal(true) } - it { expect(@link_to_file['url']).to match("/#{@project.path_with_namespace}") } - it { expect(@link_to_file['url']).to match('rails_sample.jpg') } - end - - context 'for txt file' do - before do - txt = fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') - @link_to_file = upload_file(@project.repository, txt) - end - - it { expect(@link_to_file).to have_key('alt') } - it { expect(@link_to_file).to have_key('url') } - it { expect(@link_to_file).to have_key('is_image') } - it { expect(@link_to_file).to have_value('doc_sample.txt') } - it { expect(@link_to_file['is_image']).to equal(false) } - it { expect(@link_to_file['url']).to match("/#{@project.path_with_namespace}") } - it { expect(@link_to_file['url']).to match('doc_sample.txt') } - end - - context 'for too large a file' do - before do - txt = fixture_file_upload(Rails.root + 'spec/fixtures/doc_sample.txt', 'text/plain') - allow(txt).to receive(:size) { 1000.megabytes.to_i } - @link_to_file = upload_file(@project.repository, txt) - end - - it { expect(@link_to_file).to eq(nil) } - end - end - - def upload_file(repository, file) - Projects::UploadService.new(repository, file).execute - end -end diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb deleted file mode 100644 index f57bfaea8798f19d0ca7fe145494324b8fd73c3b..0000000000000000000000000000000000000000 --- a/spec/services/search_service_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require 'spec_helper' - -describe 'Search::GlobalService' do - let(:user) { create(:user) } - let(:public_user) { create(:user) } - let(:internal_user) { create(:user) } - - let!(:found_project) { create(:empty_project, :private, name: 'searchable_project') } - let!(:unfound_project) { create(:empty_project, :private, name: 'unfound_project') } - let!(:internal_project) { create(:empty_project, :internal, name: 'searchable_internal_project') } - let!(:public_project) { create(:empty_project, :public, name: 'searchable_public_project') } - - before do - found_project.team << [user, :master] - end - - describe '#execute' do - context 'unauthenticated' do - it 'should return public projects only' do - context = Search::GlobalService.new(nil, search: "searchable") - results = context.execute - expect(results.objects('projects')).to match_array [public_project] - end - end - - context 'authenticated' do - it 'should return public, internal and private projects' do - context = Search::GlobalService.new(user, search: "searchable") - results = context.execute - expect(results.objects('projects')).to match_array [public_project, found_project, internal_project] - end - - it 'should return only public & internal projects' do - context = Search::GlobalService.new(internal_user, search: "searchable") - results = context.execute - expect(results.objects('projects')).to match_array [internal_project, public_project] - end - - it 'namespace name should be searchable' do - context = Search::GlobalService.new(user, search: found_project.namespace.path) - results = context.execute - expect(results.objects('projects')).to match_array [found_project] - end - end - end -end diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb deleted file mode 100644 index 199ac9966087ae5ed2162d856cc194a5e3b96765..0000000000000000000000000000000000000000 --- a/spec/services/system_hooks_service_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -require 'spec_helper' - -describe SystemHooksService do - let (:user) { create :user } - let (:project) { create :project } - let (:project_member) { create :project_member } - let (:key) { create(:key, user: user) } - let (:group) { create(:group) } - let (:group_member) { create(:group_member) } - - context 'event data' do - it { expect(event_data(user, :create)).to include(:event_name, :name, :created_at, :email, :user_id) } - it { expect(event_data(user, :destroy)).to include(:event_name, :name, :created_at, :email, :user_id) } - it { expect(event_data(project, :create)).to include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) } - it { expect(event_data(project, :destroy)).to include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) } - it { expect(event_data(project_member, :create)).to include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :access_level, :project_visibility) } - it { expect(event_data(project_member, :destroy)).to include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :access_level, :project_visibility) } - it { expect(event_data(key, :create)).to include(:username, :key, :id) } - it { expect(event_data(key, :destroy)).to include(:username, :key, :id) } - - it do - expect(event_data(group, :create)).to include( - :event_name, :name, :created_at, :path, :group_id, :owner_name, - :owner_email - ) - end - it do - expect(event_data(group, :destroy)).to include( - :event_name, :name, :created_at, :path, :group_id, :owner_name, - :owner_email - ) - end - it do - expect(event_data(group_member, :create)).to include( - :event_name, :created_at, :group_name, :group_path, :group_id, :user_id, - :user_name, :user_email, :group_access - ) - end - it do - expect(event_data(group_member, :destroy)).to include( - :event_name, :created_at, :group_name, :group_path, :group_id, :user_id, - :user_name, :user_email, :group_access - ) - end - end - - context 'event names' do - it { expect(event_name(user, :create)).to eq "user_create" } - it { expect(event_name(user, :destroy)).to eq "user_destroy" } - it { expect(event_name(project, :create)).to eq "project_create" } - it { expect(event_name(project, :destroy)).to eq "project_destroy" } - it { expect(event_name(project_member, :create)).to eq "user_add_to_team" } - it { expect(event_name(project_member, :destroy)).to eq "user_remove_from_team" } - it { expect(event_name(key, :create)).to eq 'key_create' } - it { expect(event_name(key, :destroy)).to eq 'key_destroy' } - it { expect(event_name(group, :create)).to eq 'group_create' } - it { expect(event_name(group, :destroy)).to eq 'group_destroy' } - it { expect(event_name(group_member, :create)).to eq 'user_add_to_group' } - it { expect(event_name(group_member, :destroy)).to eq 'user_remove_from_group' } - end - - def event_data(*args) - SystemHooksService.new.send :build_event_data, *args - end - - def event_name(*args) - SystemHooksService.new.send :build_event_name, *args - end -end diff --git a/spec/services/test_hook_service_spec.rb b/spec/services/test_hook_service_spec.rb deleted file mode 100644 index d2b505f55a250bbc4ab2a9440abde3d8f060a8a2..0000000000000000000000000000000000000000 --- a/spec/services/test_hook_service_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'spec_helper' - -describe TestHookService do - let (:user) { create :user } - let (:project) { create :project } - let (:hook) { create :project_hook, project: project } - - describe :execute do - it "should execute successfully" do - stub_request(:post, hook.url).to_return(status: 200) - expect(TestHookService.new.execute(hook, user)).to be_truthy - end - end -end diff --git a/spec/services/update_snippet_service_spec.rb b/spec/services/update_snippet_service_spec.rb deleted file mode 100644 index 841ef9bfed11e5e037b686e80a5f0ecfbae2e97a..0000000000000000000000000000000000000000 --- a/spec/services/update_snippet_service_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -require 'spec_helper' - -describe UpdateSnippetService do - before do - @user = create :user - @admin = create :user, admin: true - @opts = { - title: 'Test snippet', - file_name: 'snippet.rb', - content: 'puts "hello world"', - visibility_level: Gitlab::VisibilityLevel::PRIVATE - } - end - - context 'When public visibility is restricted' do - before do - allow_any_instance_of(ApplicationSetting).to( - receive(:restricted_visibility_levels).and_return( - [Gitlab::VisibilityLevel::PUBLIC] - ) - ) - - @snippet = create_snippet(@project, @user, @opts) - @opts.merge!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) - end - - it 'non-admins should not be able to update to public visibility' do - old_visibility = @snippet.visibility_level - update_snippet(@project, @user, @snippet, @opts) - expect(@snippet.errors.messages).to have_key(:visibility_level) - expect(@snippet.errors.messages[:visibility_level].first).to( - match('Public visibility has been restricted') - ) - expect(@snippet.visibility_level).to eq(old_visibility) - end - - it 'admins should be able to update to pubic visibility' do - old_visibility = @snippet.visibility_level - update_snippet(@project, @admin, @snippet, @opts) - expect(@snippet.visibility_level).not_to eq(old_visibility) - expect(@snippet.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC) - end - end - - def create_snippet(project, user, opts) - CreateSnippetService.new(project, user, opts).execute - end - - def update_snippet(project = nil, user, snippet, opts) - UpdateSnippetService.new(project, user, snippet, opts).execute - end -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index 53ccaa4fd6791833f2adcbaf028d579031bc2a39..0000000000000000000000000000000000000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,48 +0,0 @@ -if ENV['SIMPLECOV'] - require 'simplecov' -end - -if ENV['COVERALLS'] - require 'coveralls' - Coveralls.wear_merged! -end - -ENV["RAILS_ENV"] ||= 'test' -require File.expand_path("../../config/environment", __FILE__) -require 'rspec/rails' -require 'capybara/rails' -require 'capybara/rspec' -require 'webmock/rspec' -require 'email_spec' -require 'sidekiq/testing/inline' -require 'capybara/poltergeist' - -Capybara.javascript_driver = :poltergeist -Capybara.default_wait_time = 10 - -# Requires supporting ruby files with custom matchers and macros, etc, -# in spec/support/ and its subdirectories. -Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} - -WebMock.disable_net_connect!(allow_localhost: true) - -RSpec.configure do |config| - config.use_transactional_fixtures = false - config.use_instantiated_fixtures = false - config.mock_with :rspec - - config.include LoginHelpers, type: :feature - config.include LoginHelpers, type: :request - config.include FactoryGirl::Syntax::Methods - config.include Devise::TestHelpers, type: :controller - - config.include TestEnv - config.infer_spec_type_from_file_location! - config.raise_errors_for_deprecations! - - config.before(:suite) do - TestEnv.init - end -end - -ActiveRecord::Migration.maintain_test_schema! diff --git a/spec/support/api_helpers.rb b/spec/support/api_helpers.rb deleted file mode 100644 index ec9a326a1ea0252d8afbb21b3f89312c8038d86b..0000000000000000000000000000000000000000 --- a/spec/support/api_helpers.rb +++ /dev/null @@ -1,34 +0,0 @@ -module ApiHelpers - # Public: Prepend a request path with the path to the API - # - # path - Path to append - # user - User object - If provided, automatically appends private_token query - # string for authenticated requests - # - # Examples - # - # >> api('/issues') - # => "/api/v2/issues" - # - # >> api('/issues', User.last) - # => "/api/v2/issues?private_token=..." - # - # >> api('/issues?foo=bar', User.last) - # => "/api/v2/issues?foo=bar&private_token=..." - # - # Returns the relative path to the requested API resource - def api(path, user = nil) - "/api/#{API::API.version}#{path}" + - - # Normalize query string - (path.index('?') ? '' : '?') + - - # Append private_token if given a User object - (user.respond_to?(:private_token) ? - "&private_token=#{user.private_token}" : "") - end - - def json_response - JSON.parse(response.body) - end -end diff --git a/spec/support/db_cleaner.rb b/spec/support/db_cleaner.rb deleted file mode 100644 index cca7652093a6e17bb5013123c36a81d797231ecd..0000000000000000000000000000000000000000 --- a/spec/support/db_cleaner.rb +++ /dev/null @@ -1,50 +0,0 @@ -# RSpec.configure do |config| - -# config.around(:each) do |example| -# DatabaseCleaner.strategy = :transaction -# DatabaseCleaner.clean_with(:truncation) -# DatabaseCleaner.cleaning do -# example.run -# end -# end - -# config.around(:each, js: true) do |example| -# DatabaseCleaner.strategy = :truncation -# DatabaseCleaner.clean_with(:truncation) -# DatabaseCleaner.cleaning do -# example.run -# end -# end -# end -RSpec.configure do |config| - config.before(:suite) do - DatabaseCleaner.clean_with(:truncation) - end - - config.before(:each) do - DatabaseCleaner.strategy = :transaction - end - - config.before(:each, :js => true) do - DatabaseCleaner.strategy = :truncation - end - - config.before(:each) do - DatabaseCleaner.start - end - - config.after(:each) do - DatabaseCleaner.clean - end - - # rspec-rails 3 will no longer automatically infer an example group's spec type - # from the file location. You can explicitly opt-in to the feature using this - # config option. - # To explicitly tag specs without using automatic inference, set the `:type` - # metadata manually: - # - # describe ThingsController, :type => :controller do - # # Equivalent to being in spec/controllers - # end - config.infer_spec_type_from_file_location! -end diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb deleted file mode 100644 index 791d2a1fd648967a9455ae391b5ce9b707d6db16..0000000000000000000000000000000000000000 --- a/spec/support/login_helpers.rb +++ /dev/null @@ -1,26 +0,0 @@ -module LoginHelpers - # Internal: Create and log in as a user of the specified role - # - # role - User role (e.g., :admin, :user) - def login_as(role) - @user = create(role) - - login_with(@user) - end - - # Internal: Login as the specified user - # - # user - User instance to login with - def login_with(user) - visit new_user_session_path - fill_in "user_login", with: user.email - fill_in "user_password", with: "12345678" - click_button "Sign in" - Thread.current[:current_user] = user - end - - # Requires Javascript driver. - def logout - find(:css, ".fa.fa-sign-out").click - end -end diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb deleted file mode 100644 index 52b11bd6323c717231890d41b9e3add601f14147..0000000000000000000000000000000000000000 --- a/spec/support/matchers.rb +++ /dev/null @@ -1,79 +0,0 @@ -RSpec::Matchers.define :be_valid_commit do - match do |actual| - actual != nil - actual.id == ValidCommit::ID - actual.message == ValidCommit::MESSAGE - actual.author_name == ValidCommit::AUTHOR_FULL_NAME - end -end - -RSpec::Matchers.define :be_allowed_for do |user| - match do |url| - include UrlAccess - url_allowed?(user, url) - end -end - -RSpec::Matchers.define :be_denied_for do |user| - match do |url| - include UrlAccess - url_denied?(user, url) - end -end - -RSpec::Matchers.define :be_404_for do |user| - match do |url| - include UrlAccess - url_404?(user, url) - end -end - -RSpec::Matchers.define :include_module do |expected| - match do - described_class.included_modules.include?(expected) - end - - failure_message_for_should do - "expected #{described_class} to include the #{expected} module" - end -end - -module UrlAccess - def url_allowed?(user, url) - emulate_user(user) - visit url - (status_code != 404 && current_path != new_user_session_path) - end - - def url_denied?(user, url) - emulate_user(user) - visit url - (status_code == 404 || current_path == new_user_session_path) - end - - def url_404?(user, url) - emulate_user(user) - visit url - status_code == 404 - end - - def emulate_user(user) - user = case user - when :user then create(:user) - when :visitor then nil - when :admin then create(:admin) - else user - end - login_with(user) if user - end -end - -# Extend shoulda-matchers -module Shoulda::Matchers::ActiveModel - class EnsureLengthOfMatcher - # Shortcut for is_at_least and is_at_most - def is_within(range) - is_at_least(range.min) && is_at_most(range.max) - end - end -end diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb deleted file mode 100644 index 305592fa5a656fcaa937cea525fee7e4c0fad05d..0000000000000000000000000000000000000000 --- a/spec/support/mentionable_shared_examples.rb +++ /dev/null @@ -1,115 +0,0 @@ -# Specifications for behavior common to all Mentionable implementations. -# Requires a shared context containing: -# - let(:subject) { "the mentionable implementation" } -# - let(:backref_text) { "the way that +subject+ should refer to itself in backreferences " } -# - let(:set_mentionable_text) { lambda { |txt| "block that assigns txt to the subject's mentionable_text" } } - -def common_mentionable_setup - # Avoid name collisions with let(:project) or let(:author) in the surrounding scope. - let(:mproject) { create :project } - let(:mauthor) { subject.author } - - let(:mentioned_issue) { create :issue, project: mproject } - let(:other_issue) { create :issue, project: mproject } - let(:mentioned_mr) { create :merge_request, :simple, source_project: mproject } - let(:mentioned_commit) { double('commit', sha: '1234567890abcdef').as_null_object } - - let(:ext_proj) { create :project, :public } - let(:ext_issue) { create :issue, project: ext_proj } - let(:other_ext_issue) { create :issue, project: ext_proj } - let(:ext_mr) { create :merge_request, :simple, source_project: ext_proj } - let(:ext_commit) { ext_proj.repository.commit } - - # Override to add known commits to the repository stub. - let(:extra_commits) { [] } - - # A string that mentions each of the +mentioned_.*+ objects above. Mentionables should add a self-reference - # to this string and place it in their +mentionable_text+. - let(:ref_string) do - "mentions ##{mentioned_issue.iid} twice ##{mentioned_issue.iid}, " + - "!#{mentioned_mr.iid}, " + - "#{ext_proj.path_with_namespace}##{ext_issue.iid}, " + - "#{ext_proj.path_with_namespace}!#{ext_mr.iid}, " + - "#{ext_proj.path_with_namespace}@#{ext_commit.short_id}, " + - "#{mentioned_commit.sha[0..10]} and itself as #{backref_text}" - end - - before do - # Wire the project's repository to return the mentioned commit, and +nil+ for any - # unrecognized commits. - commitmap = { '1234567890a' => mentioned_commit } - extra_commits.each { |c| commitmap[c.short_id] = c } - allow(mproject.repository).to receive(:commit) { |sha| commitmap[sha] } - set_mentionable_text.call(ref_string) - end -end - -shared_examples 'a mentionable' do - common_mentionable_setup - - it 'generates a descriptive back-reference' do - expect(subject.gfm_reference).to eq(backref_text) - end - - it "extracts references from its reference property" do - # De-duplicate and omit itself - refs = subject.references(mproject) - expect(refs.size).to eq(6) - expect(refs).to include(mentioned_issue) - expect(refs).to include(mentioned_mr) - expect(refs).to include(mentioned_commit) - expect(refs).to include(ext_issue) - expect(refs).to include(ext_mr) - expect(refs).to include(ext_commit) - end - - it 'creates cross-reference notes' do - mentioned_objects = [mentioned_issue, mentioned_mr, mentioned_commit, - ext_issue, ext_mr, ext_commit] - - mentioned_objects.each do |referenced| - expect(Note).to receive(:create_cross_reference_note).with(referenced, subject.local_reference, mauthor, mproject) - end - - subject.create_cross_references!(mproject, mauthor) - end - - it 'detects existing cross-references' do - Note.create_cross_reference_note(mentioned_issue, subject.local_reference, mauthor, mproject) - - expect(subject.has_mentioned?(mentioned_issue)).to be_truthy - expect(subject.has_mentioned?(mentioned_mr)).to be_falsey - end -end - -shared_examples 'an editable mentionable' do - common_mentionable_setup - - it_behaves_like 'a mentionable' - - it 'creates new cross-reference notes when the mentionable text is edited' do - new_text = "still mentions ##{mentioned_issue.iid}, " + - "#{mentioned_commit.sha[0..10]}, " + - "#{ext_issue.iid}, " + - "new refs: ##{other_issue.iid}, " + - "#{ext_proj.path_with_namespace}##{other_ext_issue.iid}" - - [mentioned_issue, mentioned_commit, ext_issue].each do |oldref| - expect(Note).not_to receive(:create_cross_reference_note).with(oldref, subject.local_reference, - mauthor, mproject) - end - - [other_issue, other_ext_issue].each do |newref| - expect(Note).to receive(:create_cross_reference_note).with( - newref, - subject.local_reference, - mauthor, - mproject - ) - end - - subject.save - set_mentionable_text.call(new_text) - subject.notice_added_references(mproject, mauthor) - end -end diff --git a/spec/support/repo_helpers.rb b/spec/support/repo_helpers.rb deleted file mode 100644 index aadf791bf3ff1ee5c245dc11e31dd1ac1d6f8d25..0000000000000000000000000000000000000000 --- a/spec/support/repo_helpers.rb +++ /dev/null @@ -1,118 +0,0 @@ -module RepoHelpers - extend self - - # Text file in repo - # - # Ex. - # - # # Get object - # blob = RepoHelpers.text_blob - # - # blob.path # => 'files/js/commit.js.coffee' - # blob.data # => 'class Commit...' - # - def sample_blob - OpenStruct.new( - oid: '5f53439ca4b009096571d3c8bc3d09d30e7431b3', - path: "files/js/commit.js.coffee", - data: < - $('.files .diff-file').each -> - new CommitFile(this) - -@Commit = Commit -eos - ) - end - - def sample_commit - OpenStruct.new( - id: "570e7b2abdd848b95f2f578043fc23bd6f6fd24d", - parent_id: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', - author_full_name: "Dmitriy Zaporozhets", - author_email: "dmitriy.zaporozhets@gmail.com", - files_changed_count: 2, - line_code: '2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_14', - line_code_path: 'files/ruby/popen.rb', - del_line_code: '2f6fcd96b88b36ce98c38da085c795a27d92a3dd_13_13', - message: < -eos - ) - end - - def another_sample_commit - OpenStruct.new( - id: "e56497bb5f03a90a51293fc6d516788730953899", - parent_id: '4cd80ccab63c82b4bad16faa5193fbd2aa06df40', - author_full_name: "Sytse Sijbrandij", - author_email: "sytse@gitlab.com", - files_changed_count: 1, - message: < -eos - ) - end - - def sample_image_commit - OpenStruct.new( - id: "2f63565e7aac07bcdadb654e253078b727143ec4", - author_full_name: "Dmitriy Zaporozhets", - author_email: "dmitriy.zaporozhets@gmail.com", - old_blob_id: '33f3729a45c02fc67d00adb1b8bca394b0e761d9', - new_blob_id: '2f63565e7aac07bcdadb654e253078b727143ec4', - message: < -eos - ) - end - - def sample_compare - changes = [ - { - line_code: 'a5cc2925ca8258af241be7e5b0381edf30266302_20_20', - file_path: '.gitignore', - }, - { - line_code: '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44_4_6', - file_path: '.gitmodules', - } - ] - - commits = [ - '5937ac0a7beb003549fc5fd26fc247adbce4a52e', - '570e7b2abdd848b95f2f578043fc23bd6f6fd24d', - '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', - 'd14d6c0abdd253381df51a723d58691b2ee1ab08', - 'c1acaa58bbcbc3eafe538cb8274ba387047b69f8', - ].reverse # last commit is recent one - - OpenStruct.new( - source_branch: 'master', - target_branch: 'feature', - changes: changes, - commits: commits - ) - end -end diff --git a/spec/support/select2_helper.rb b/spec/support/select2_helper.rb deleted file mode 100644 index 691f84f39d477335d54c845799abc892bf2278e0..0000000000000000000000000000000000000000 --- a/spec/support/select2_helper.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Select2 ajax programmatic helper -# It allows you to select value from select2 -# -# Params -# value - real value of selected item -# opts - options containing css selector -# -# Usage: -# -# select2(2, from: '#user_ids') -# - -module Select2Helper - def select2(value, options={}) - raise "Must pass a hash containing 'from'" if not options.is_a?(Hash) or not options.has_key?(:from) - - selector = options[:from] - - if options[:multiple] - execute_script("$('#{selector}').select2('val', ['#{value}'], true);") - else - execute_script("$('#{selector}').select2('val', '#{value}', true);") - end - end -end diff --git a/spec/support/taskable_shared_examples.rb b/spec/support/taskable_shared_examples.rb deleted file mode 100644 index 490f453d4684cb027b0362db842ba5d7b0ff3b76..0000000000000000000000000000000000000000 --- a/spec/support/taskable_shared_examples.rb +++ /dev/null @@ -1,42 +0,0 @@ -# Specs for task state functionality for issues and merge requests. -# -# Requires a context containing: -# let(:subject) { Issue or MergeRequest } -shared_examples 'a Taskable' do - before do - subject.description = < 'e56497b', - 'feature' => '0b4bc9a', - 'feature_conflict' => 'bb5206f', - 'fix' => '12d65c8', - 'improve/awesome' => '5937ac0', - 'markdown' => '0ed8c6c', - 'master' => '5937ac0' - } - - # Test environment - # - # See gitlab.yml.example test section for paths - # - def init(opts = {}) - # Disable mailer for spinach tests - disable_mailer if opts[:mailer] == false - - clean_test_path - - FileUtils.mkdir_p(repos_path) - - # Setup GitLab shell for test instance - setup_gitlab_shell - - # Create repository for FactoryGirl.create(:project) - setup_factory_repo - end - - def disable_mailer - NotificationService.any_instance.stub(mailer: double.as_null_object) - end - - def enable_mailer - allow_any_instance_of(NotificationService).to receive(:mailer).and_call_original - end - - # Clean /tmp/tests - # - # Keeps gitlab-shell and gitlab-test - def clean_test_path - tmp_test_path = Rails.root.join('tmp', 'tests', '**') - - Dir[tmp_test_path].each do |entry| - unless File.basename(entry) =~ /\Agitlab-(shell|test)\z/ - FileUtils.rm_rf(entry) - end - end - end - - def setup_gitlab_shell - unless File.directory?(Rails.root.join(*%w(tmp tests gitlab-shell))) - `rake gitlab:shell:install` - end - end - - def setup_factory_repo - clone_url = "https://gitlab.com/gitlab-org/#{factory_repo_name}.git" - - unless File.directory?(factory_repo_path) - system(*%W(git clone -q #{clone_url} #{factory_repo_path})) - end - - Dir.chdir(factory_repo_path) do - BRANCH_SHA.each do |branch, sha| - # Try to reset without fetching to avoid using the network. - reset = %W(git update-ref refs/heads/#{branch} #{sha}) - unless system(*reset) - if system(*%w(git fetch origin)) - unless system(*reset) - raise 'The fetched test seed '\ - 'does not contain the required revision.' - end - else - raise 'Could not fetch test seed repository.' - end - end - end - end - - # We must copy bare repositories because we will push to them. - system(git_env, *%W(git clone -q --bare #{factory_repo_path} #{factory_repo_path_bare})) - end - - def copy_repo(project) - base_repo_path = File.expand_path(factory_repo_path_bare) - target_repo_path = File.expand_path(repos_path + "/#{project.namespace.path}/#{project.path}.git") - FileUtils.mkdir_p(target_repo_path) - FileUtils.cp_r("#{base_repo_path}/.", target_repo_path) - FileUtils.chmod_R 0755, target_repo_path - end - - def repos_path - Gitlab.config.gitlab_shell.repos_path - end - - private - - def factory_repo_path - @factory_repo_path ||= Rails.root.join('tmp', 'tests', factory_repo_name) - end - - def factory_repo_path_bare - "#{factory_repo_path}_bare" - end - - def factory_repo_name - 'gitlab-test' - end - - # Prevent developer git configurations from being persisted to test - # repositories - def git_env - {'GIT_TEMPLATE_DIR' => ''} - end -end diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb deleted file mode 100644 index a59f74c21219169a4481281680b36ed4d7b1f1e7..0000000000000000000000000000000000000000 --- a/spec/tasks/gitlab/backup_rake_spec.rb +++ /dev/null @@ -1,152 +0,0 @@ -require 'spec_helper' -require 'rake' - -describe 'gitlab:app namespace rake task' do - before :all do - Rake.application.rake_require "tasks/gitlab/task_helpers" - Rake.application.rake_require "tasks/gitlab/backup" - Rake.application.rake_require "tasks/gitlab/shell" - # empty task as env is already loaded - Rake::Task.define_task :environment - end - - def run_rake_task(task_name) - Rake::Task[task_name].reenable - Rake.application.invoke_task task_name - end - - describe 'backup_restore' do - before do - # avoid writing task output to spec progress - allow($stdout).to receive :write - end - - context 'gitlab version' do - before do - Dir.stub glob: [] - allow(Dir).to receive :chdir - File.stub exists?: true - Kernel.stub system: true - FileUtils.stub cp_r: true - FileUtils.stub mv: true - Rake::Task["gitlab:shell:setup"].stub invoke: true - end - - let(:gitlab_version) { Gitlab::VERSION } - - it 'should fail on mismatch' do - YAML.stub load_file: {gitlab_version: "not #{gitlab_version}" } - expect { run_rake_task('gitlab:backup:restore') }.to( - raise_error SystemExit - ) - end - - it 'should invoke restoration on mach' do - YAML.stub load_file: {gitlab_version: gitlab_version} - expect(Rake::Task["gitlab:backup:db:restore"]).to receive :invoke - expect(Rake::Task["gitlab:backup:repo:restore"]).to receive :invoke - expect(Rake::Task["gitlab:shell:setup"]).to receive :invoke - expect { run_rake_task('gitlab:backup:restore') }.to_not raise_error - end - end - - end # backup_restore task - - describe 'backup_create' do - def tars_glob - Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar')) - end - - before :all do - # Record the existing backup tars so we don't touch them - existing_tars = tars_glob - - # Redirect STDOUT and run the rake task - orig_stdout = $stdout - $stdout = StringIO.new - run_rake_task('gitlab:backup:create') - $stdout = orig_stdout - - @backup_tar = (tars_glob - existing_tars).first - end - - after :all do - FileUtils.rm(@backup_tar) - end - - it 'should set correct permissions on the tar file' do - expect(File.exist?(@backup_tar)).to be_truthy - expect(File::Stat.new(@backup_tar).mode.to_s(8)).to eq('100600') - end - - it 'should set correct permissions on the tar contents' do - tar_contents, exit_status = Gitlab::Popen.popen( - %W{tar -tvf #{@backup_tar} db uploads repositories} - ) - expect(exit_status).to eq(0) - expect(tar_contents).to match('db/') - expect(tar_contents).to match('uploads/') - expect(tar_contents).to match('repositories/') - expect(tar_contents).not_to match(/^.{4,9}[rwx].* (db|uploads|repositories)\/$/) - end - - it 'should delete temp directories' do - temp_dirs = Dir.glob( - File.join(Gitlab.config.backup.path, '{db,repositories,uploads}') - ) - - expect(temp_dirs).to be_empty - end - end # backup_create task - - describe "Skipping items" do - def tars_glob - Dir.glob(File.join(Gitlab.config.backup.path, '*_gitlab_backup.tar')) - end - - before :all do - @origin_cd = Dir.pwd - - Rake::Task["gitlab:backup:db:create"].reenable - Rake::Task["gitlab:backup:repo:create"].reenable - Rake::Task["gitlab:backup:uploads:create"].reenable - - # Record the existing backup tars so we don't touch them - existing_tars = tars_glob - - # Redirect STDOUT and run the rake task - orig_stdout = $stdout - $stdout = StringIO.new - ENV["SKIP"] = "repositories" - run_rake_task('gitlab:backup:create') - $stdout = orig_stdout - - @backup_tar = (tars_glob - existing_tars).first - end - - after :all do - FileUtils.rm(@backup_tar) - Dir.chdir @origin_cd - end - - it "does not contain skipped item" do - tar_contents, exit_status = Gitlab::Popen.popen( - %W{tar -tvf #{@backup_tar} db uploads repositories} - ) - - expect(tar_contents).to match('db/') - expect(tar_contents).to match('uploads/') - expect(tar_contents).not_to match('repositories/') - end - - it 'does not invoke repositories restore' do - Rake::Task["gitlab:shell:setup"].stub invoke: true - allow($stdout).to receive :write - - expect(Rake::Task["gitlab:backup:db:restore"]).to receive :invoke - expect(Rake::Task["gitlab:backup:repo:restore"]).not_to receive :invoke - expect(Rake::Task["gitlab:shell:setup"]).to receive :invoke - expect { run_rake_task('gitlab:backup:restore') }.to_not raise_error - end - end -end # gitlab:app namespace diff --git a/spec/tasks/gitlab/mail_google_schema_whitelisting.rb b/spec/tasks/gitlab/mail_google_schema_whitelisting.rb deleted file mode 100644 index 22e746870dc701cee6518b165970ff49df06a442..0000000000000000000000000000000000000000 --- a/spec/tasks/gitlab/mail_google_schema_whitelisting.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' -require 'rake' - -describe 'gitlab:mail_google_schema_whitelisting rake task' do - before :all do - Rake.application.rake_require "tasks/gitlab/task_helpers" - Rake.application.rake_require "tasks/gitlab/mail_google_schema_whitelisting" - # empty task as env is already loaded - Rake::Task.define_task :environment - end - - describe 'call' do - before do - # avoid writing task output to spec progress - allow($stdout).to receive :write - end - - let :run_rake_task do - Rake::Task["gitlab:mail_google_schema_whitelisting"].reenable - Rake.application.invoke_task "gitlab:mail_google_schema_whitelisting" - end - - it 'should run the task without errors' do - expect { run_rake_task }.to_not raise_error - end - end -end diff --git a/spec/workers/fork_registration_worker_spec.rb b/spec/workers/fork_registration_worker_spec.rb deleted file mode 100644 index cc6f574b29c640977822092cb268ea8845e05cd3..0000000000000000000000000000000000000000 --- a/spec/workers/fork_registration_worker_spec.rb +++ /dev/null @@ -1,10 +0,0 @@ - -require 'spec_helper' - -describe ForkRegistrationWorker do - context "as a resque worker" do - it "reponds to #perform" do - expect(ForkRegistrationWorker.new).to respond_to(:perform) - end - end -end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb deleted file mode 100644 index df1a2b84a53c644d443e40f1d536e4f45ba31fc2..0000000000000000000000000000000000000000 --- a/spec/workers/post_receive_spec.rb +++ /dev/null @@ -1,45 +0,0 @@ -require 'spec_helper' - -describe PostReceive do - let(:changes) { "123456 789012 refs/heads/tést\n654321 210987 refs/tags/tag" } - let(:wrongly_encoded_changes) { changes.encode("ISO-8859-1").force_encoding("UTF-8") } - let(:base64_changes) { Base64.encode64(wrongly_encoded_changes) } - - context "as a resque worker" do - it "reponds to #perform" do - expect(PostReceive.new).to respond_to(:perform) - end - end - - context "web hook" do - let(:project) { create(:project) } - let(:key) { create(:key, user: project.owner) } - let(:key_id) { key.shell_id } - - it "fetches the correct project" do - expect(Project).to receive(:find_with_namespace).with(project.path_with_namespace).and_return(project) - PostReceive.new.perform(pwd(project), key_id, base64_changes) - end - - it "does not run if the author is not in the project" do - allow(Key).to receive(:find_by).with(hash_including(id: anything())) { nil } - - expect(project).not_to receive(:execute_hooks) - - expect(PostReceive.new.perform(pwd(project), key_id, base64_changes)).to be_falsey - end - - it "asks the project to trigger all hooks" do - Project.stub(find_with_namespace: project) - expect(project).to receive(:execute_hooks).twice - expect(project).to receive(:execute_services).twice - expect(project).to receive(:update_merge_requests) - - PostReceive.new.perform(pwd(project), key_id, base64_changes) - end - end - - def pwd(project) - File.join(Gitlab.config.gitlab_shell.repos_path, project.path_with_namespace) - end -end diff --git a/spec/workers/repository_archive_worker_spec.rb b/spec/workers/repository_archive_worker_spec.rb deleted file mode 100644 index c2362058cfdeee8f36f0e1ccc39501eafd1ef18e..0000000000000000000000000000000000000000 --- a/spec/workers/repository_archive_worker_spec.rb +++ /dev/null @@ -1,80 +0,0 @@ -require 'spec_helper' - -describe RepositoryArchiveWorker do - let(:project) { create(:project) } - subject { RepositoryArchiveWorker.new } - - before do - allow(Project).to receive(:find).and_return(project) - end - - describe "#perform" do - it "cleans old archives" do - expect(project.repository).to receive(:clean_old_archives) - - subject.perform(project.id, "master", "zip") - end - - context "when the repository doesn't have an archive file path" do - before do - allow(project.repository).to receive(:archive_file_path).and_return(nil) - end - - it "doesn't archive the repo" do - expect(project.repository).not_to receive(:archive_repo) - - subject.perform(project.id, "master", "zip") - end - end - - context "when the repository has an archive file path" do - let(:file_path) { "/archive.zip" } - let(:pid_file_path) { "/archive.zip.pid" } - - before do - allow(project.repository).to receive(:archive_file_path).and_return(file_path) - allow(project.repository).to receive(:archive_pid_file_path).and_return(pid_file_path) - end - - context "when the archive file already exists" do - before do - allow(File).to receive(:exist?).with(file_path).and_return(true) - end - - it "doesn't archive the repo" do - expect(project.repository).not_to receive(:archive_repo) - - subject.perform(project.id, "master", "zip") - end - end - - context "when the archive file doesn't exist yet" do - before do - allow(File).to receive(:exist?).with(file_path).and_return(false) - allow(File).to receive(:exist?).with(pid_file_path).and_return(true) - end - - context "when the archive pid file doesn't exist yet" do - before do - allow(File).to receive(:exist?).with(pid_file_path).and_return(false) - end - - it "archives the repo" do - expect(project.repository).to receive(:archive_repo) - - subject.perform(project.id, "master", "zip") - end - end - - context "when the archive pid file already exists" do - it "doesn't archive the repo" do - expect(project.repository).not_to receive(:archive_repo) - - subject.perform(project.id, "master", "zip") - end - end - end - end - end -end - diff --git a/tmp/.gitkeep b/tmp/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/tmp/pids/.gitkeep b/tmp/pids/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/tmp/sockets/.gitkeep b/tmp/sockets/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/vendor/assets/javascripts/chart-lib.min.js b/vendor/assets/javascripts/chart-lib.min.js deleted file mode 100644 index 3a0a2c87345f54eac4a8da8a9e1a81868c645ec7..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/chart-lib.min.js +++ /dev/null @@ -1,11 +0,0 @@ -/*! - * Chart.js - * http://chartjs.org/ - * Version: 1.0.2 - * - * Copyright 2015 Nick Downie - * Released under the MIT license - * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md - */ -(function(){"use strict";var t=this,i=t.Chart,e=function(t){this.canvas=t.canvas,this.ctx=t;var i=function(t,i){return t["offset"+i]?t["offset"+i]:document.defaultView.getComputedStyle(t).getPropertyValue(i)},e=this.width=i(t.canvas,"Width"),n=this.height=i(t.canvas,"Height");t.canvas.width=e,t.canvas.height=n;var e=this.width=t.canvas.width,n=this.height=t.canvas.height;return this.aspectRatio=this.width/this.height,s.retinaScale(this),this};e.defaults={global:{animation:!0,animationSteps:60,animationEasing:"easeOutQuart",showScale:!0,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleIntegersOnly:!0,scaleBeginAtZero:!1,scaleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",responsive:!1,maintainAspectRatio:!0,showTooltips:!0,customTooltips:!1,tooltipEvents:["mousemove","touchstart","touchmove","mouseout"],tooltipFillColor:"rgba(0,0,0,0.8)",tooltipFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipFontSize:14,tooltipFontStyle:"normal",tooltipFontColor:"#fff",tooltipTitleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipTitleFontSize:14,tooltipTitleFontStyle:"bold",tooltipTitleFontColor:"#fff",tooltipYPadding:6,tooltipXPadding:6,tooltipCaretSize:8,tooltipCornerRadius:6,tooltipXOffset:10,tooltipTemplate:"<%if (label){%><%=label%>: <%}%><%= value %>",multiTooltipTemplate:"<%= value %>",multiTooltipKeyBackground:"#fff",onAnimationProgress:function(){},onAnimationComplete:function(){}}},e.types={};var s=e.helpers={},n=s.each=function(t,i,e){var s=Array.prototype.slice.call(arguments,3);if(t)if(t.length===+t.length){var n;for(n=0;n=0;s--){var n=t[s];if(i(n))return n}},s.inherits=function(t){var i=this,e=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return i.apply(this,arguments)},s=function(){this.constructor=e};return s.prototype=i.prototype,e.prototype=new s,e.extend=r,t&&a(e.prototype,t),e.__super__=i.prototype,e}),c=s.noop=function(){},u=s.uid=function(){var t=0;return function(){return"chart-"+t++}}(),d=s.warn=function(t){window.console&&"function"==typeof window.console.warn&&console.warn(t)},p=s.amd="function"==typeof define&&define.amd,f=s.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},g=s.max=function(t){return Math.max.apply(Math,t)},m=s.min=function(t){return Math.min.apply(Math,t)},v=(s.cap=function(t,i,e){if(f(i)){if(t>i)return i}else if(f(e)&&e>t)return e;return t},s.getDecimalPlaces=function(t){return t%1!==0&&f(t)?t.toString().split(".")[1].length:0}),S=s.radians=function(t){return t*(Math.PI/180)},x=(s.getAngleFromPoint=function(t,i){var e=i.x-t.x,s=i.y-t.y,n=Math.sqrt(e*e+s*s),o=2*Math.PI+Math.atan2(s,e);return 0>e&&0>s&&(o+=2*Math.PI),{angle:o,distance:n}},s.aliasPixel=function(t){return t%2===0?0:.5}),y=(s.splineCurve=function(t,i,e,s){var n=Math.sqrt(Math.pow(i.x-t.x,2)+Math.pow(i.y-t.y,2)),o=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),a=s*n/(n+o),h=s*o/(n+o);return{inner:{x:i.x-a*(e.x-t.x),y:i.y-a*(e.y-t.y)},outer:{x:i.x+h*(e.x-t.x),y:i.y+h*(e.y-t.y)}}},s.calculateOrderOfMagnitude=function(t){return Math.floor(Math.log(t)/Math.LN10)}),C=(s.calculateScaleRange=function(t,i,e,s,n){var o=2,a=Math.floor(i/(1.5*e)),h=o>=a,l=g(t),r=m(t);l===r&&(l+=.5,r>=.5&&!s?r-=.5:l+=.5);for(var c=Math.abs(l-r),u=y(c),d=Math.ceil(l/(1*Math.pow(10,u)))*Math.pow(10,u),p=s?0:Math.floor(r/(1*Math.pow(10,u)))*Math.pow(10,u),f=d-p,v=Math.pow(10,u),S=Math.round(f/v);(S>a||a>2*S)&&!h;)if(S>a)v*=2,S=Math.round(f/v),S%1!==0&&(h=!0);else if(n&&u>=0){if(v/2%1!==0)break;v/=2,S=Math.round(f/v)}else v/=2,S=Math.round(f/v);return h&&(S=o,v=f/S),{steps:S,stepValue:v,min:p,max:p+S*v}},s.template=function(t,i){function e(t,i){var e=/\W/.test(t)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+t.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):s[t]=s[t];return i?e(i):e}if(t instanceof Function)return t(i);var s={};return e(t,i)}),w=(s.generateLabels=function(t,i,e,s){var o=new Array(i);return labelTemplateString&&n(o,function(i,n){o[n]=C(t,{value:e+s*(n+1)})}),o},s.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),st?-.5*s*Math.pow(2,10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e):s*Math.pow(2,-10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e)*.5+1)},easeInBack:function(t){var i=1.70158;return 1*(t/=1)*t*((i+1)*t-i)},easeOutBack:function(t){var i=1.70158;return 1*((t=t/1-1)*t*((i+1)*t+i)+1)},easeInOutBack:function(t){var i=1.70158;return(t/=.5)<1?.5*t*t*(((i*=1.525)+1)*t-i):.5*((t-=2)*t*(((i*=1.525)+1)*t+i)+2)},easeInBounce:function(t){return 1-w.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?7.5625*t*t:2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*w.easeInBounce(2*t):.5*w.easeOutBounce(2*t-1)+.5}}),b=s.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),P=s.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),L=(s.animationLoop=function(t,i,e,s,n,o){var a=0,h=w[e]||w.linear,l=function(){a++;var e=a/i,r=h(e);t.call(o,r,e,a),s.call(o,r,e),i>a?o.animationFrame=b(l):n.apply(o)};b(l)},s.getRelativePosition=function(t){var i,e,s=t.originalEvent||t,n=t.currentTarget||t.srcElement,o=n.getBoundingClientRect();return s.touches?(i=s.touches[0].clientX-o.left,e=s.touches[0].clientY-o.top):(i=s.clientX-o.left,e=s.clientY-o.top),{x:i,y:e}},s.addEvent=function(t,i,e){t.addEventListener?t.addEventListener(i,e):t.attachEvent?t.attachEvent("on"+i,e):t["on"+i]=e}),k=s.removeEvent=function(t,i,e){t.removeEventListener?t.removeEventListener(i,e,!1):t.detachEvent?t.detachEvent("on"+i,e):t["on"+i]=c},F=(s.bindEvents=function(t,i,e){t.events||(t.events={}),n(i,function(i){t.events[i]=function(){e.apply(t,arguments)},L(t.chart.canvas,i,t.events[i])})},s.unbindEvents=function(t,i){n(i,function(i,e){k(t.chart.canvas,e,i)})}),R=s.getMaximumWidth=function(t){var i=t.parentNode;return i.clientWidth},T=s.getMaximumHeight=function(t){var i=t.parentNode;return i.clientHeight},A=(s.getMaximumSize=s.getMaximumWidth,s.retinaScale=function(t){var i=t.ctx,e=t.canvas.width,s=t.canvas.height;window.devicePixelRatio&&(i.canvas.style.width=e+"px",i.canvas.style.height=s+"px",i.canvas.height=s*window.devicePixelRatio,i.canvas.width=e*window.devicePixelRatio,i.scale(window.devicePixelRatio,window.devicePixelRatio))}),M=s.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},W=s.fontString=function(t,i,e){return i+" "+t+"px "+e},z=s.longestText=function(t,i,e){t.font=i;var s=0;return n(e,function(i){var e=t.measureText(i).width;s=e>s?e:s}),s},B=s.drawRoundedRectangle=function(t,i,e,s,n,o){t.beginPath(),t.moveTo(i+o,e),t.lineTo(i+s-o,e),t.quadraticCurveTo(i+s,e,i+s,e+o),t.lineTo(i+s,e+n-o),t.quadraticCurveTo(i+s,e+n,i+s-o,e+n),t.lineTo(i+o,e+n),t.quadraticCurveTo(i,e+n,i,e+n-o),t.lineTo(i,e+o),t.quadraticCurveTo(i,e,i+o,e),t.closePath()};e.instances={},e.Type=function(t,i,s){this.options=i,this.chart=s,this.id=u(),e.instances[this.id]=this,i.responsive&&this.resize(),this.initialize.call(this,t)},a(e.Type.prototype,{initialize:function(){return this},clear:function(){return M(this.chart),this},stop:function(){return P(this.animationFrame),this},resize:function(t){this.stop();var i=this.chart.canvas,e=R(this.chart.canvas),s=this.options.maintainAspectRatio?e/this.chart.aspectRatio:T(this.chart.canvas);return i.width=this.chart.width=e,i.height=this.chart.height=s,A(this.chart),"function"==typeof t&&t.apply(this,Array.prototype.slice.call(arguments,1)),this},reflow:c,render:function(t){return t&&this.reflow(),this.options.animation&&!t?s.animationLoop(this.draw,this.options.animationSteps,this.options.animationEasing,this.options.onAnimationProgress,this.options.onAnimationComplete,this):(this.draw(),this.options.onAnimationComplete.call(this)),this},generateLegend:function(){return C(this.options.legendTemplate,this)},destroy:function(){this.clear(),F(this,this.events);var t=this.chart.canvas;t.width=this.chart.width,t.height=this.chart.height,t.style.removeProperty?(t.style.removeProperty("width"),t.style.removeProperty("height")):(t.style.removeAttribute("width"),t.style.removeAttribute("height")),delete e.instances[this.id]},showTooltip:function(t,i){"undefined"==typeof this.activeElements&&(this.activeElements=[]);var o=function(t){var i=!1;return t.length!==this.activeElements.length?i=!0:(n(t,function(t,e){t!==this.activeElements[e]&&(i=!0)},this),i)}.call(this,t);if(o||i){if(this.activeElements=t,this.draw(),this.options.customTooltips&&this.options.customTooltips(!1),t.length>0)if(this.datasets&&this.datasets.length>1){for(var a,h,r=this.datasets.length-1;r>=0&&(a=this.datasets[r].points||this.datasets[r].bars||this.datasets[r].segments,h=l(a,t[0]),-1===h);r--);var c=[],u=[],d=function(){var t,i,e,n,o,a=[],l=[],r=[];return s.each(this.datasets,function(i){t=i.points||i.bars||i.segments,t[h]&&t[h].hasValue()&&a.push(t[h])}),s.each(a,function(t){l.push(t.x),r.push(t.y),c.push(s.template(this.options.multiTooltipTemplate,t)),u.push({fill:t._saved.fillColor||t.fillColor,stroke:t._saved.strokeColor||t.strokeColor})},this),o=m(r),e=g(r),n=m(l),i=g(l),{x:n>this.chart.width/2?n:i,y:(o+e)/2}}.call(this,h);new e.MultiTooltip({x:d.x,y:d.y,xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,xOffset:this.options.tooltipXOffset,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,titleTextColor:this.options.tooltipTitleFontColor,titleFontFamily:this.options.tooltipTitleFontFamily,titleFontStyle:this.options.tooltipTitleFontStyle,titleFontSize:this.options.tooltipTitleFontSize,cornerRadius:this.options.tooltipCornerRadius,labels:c,legendColors:u,legendColorBackground:this.options.multiTooltipKeyBackground,title:t[0].label,chart:this.chart,ctx:this.chart.ctx,custom:this.options.customTooltips}).draw()}else n(t,function(t){var i=t.tooltipPosition();new e.Tooltip({x:Math.round(i.x),y:Math.round(i.y),xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,caretHeight:this.options.tooltipCaretSize,cornerRadius:this.options.tooltipCornerRadius,text:C(this.options.tooltipTemplate,t),chart:this.chart,custom:this.options.customTooltips}).draw()},this);return this}},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)}}),e.Type.extend=function(t){var i=this,s=function(){return i.apply(this,arguments)};if(s.prototype=o(i.prototype),a(s.prototype,t),s.extend=e.Type.extend,t.name||i.prototype.name){var n=t.name||i.prototype.name,l=e.defaults[i.prototype.name]?o(e.defaults[i.prototype.name]):{};e.defaults[n]=a(l,t.defaults),e.types[n]=s,e.prototype[n]=function(t,i){var o=h(e.defaults.global,e.defaults[n],i||{});return new s(t,o,this)}}else d("Name not provided for this chart, so it hasn't been registered");return i},e.Element=function(t){a(this,t),this.initialize.apply(this,arguments),this.save()},a(e.Element.prototype,{initialize:function(){},restore:function(t){return t?n(t,function(t){this[t]=this._saved[t]},this):a(this,this._saved),this},save:function(){return this._saved=o(this),delete this._saved._saved,this},update:function(t){return n(t,function(t,i){this._saved[i]=this[i],this[i]=t},this),this},transition:function(t,i){return n(t,function(t,e){this[e]=(t-this._saved[e])*i+this._saved[e]},this),this},tooltipPosition:function(){return{x:this.x,y:this.y}},hasValue:function(){return f(this.value)}}),e.Element.extend=r,e.Point=e.Element.extend({display:!0,inRange:function(t,i){var e=this.hitDetectionRadius+this.radius;return Math.pow(t-this.x,2)+Math.pow(i-this.y,2)=this.startAngle&&e.angle<=this.endAngle,o=e.distance>=this.innerRadius&&e.distance<=this.outerRadius;return n&&o},tooltipPosition:function(){var t=this.startAngle+(this.endAngle-this.startAngle)/2,i=(this.outerRadius-this.innerRadius)/2+this.innerRadius;return{x:this.x+Math.cos(t)*i,y:this.y+Math.sin(t)*i}},draw:function(t){var i=this.ctx;i.beginPath(),i.arc(this.x,this.y,this.outerRadius,this.startAngle,this.endAngle),i.arc(this.x,this.y,this.innerRadius,this.endAngle,this.startAngle,!0),i.closePath(),i.strokeStyle=this.strokeColor,i.lineWidth=this.strokeWidth,i.fillStyle=this.fillColor,i.fill(),i.lineJoin="bevel",this.showStroke&&i.stroke()}}),e.Rectangle=e.Element.extend({draw:function(){var t=this.ctx,i=this.width/2,e=this.x-i,s=this.x+i,n=this.base-(this.base-this.y),o=this.strokeWidth/2;this.showStroke&&(e+=o,s-=o,n+=o),t.beginPath(),t.fillStyle=this.fillColor,t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.moveTo(e,this.base),t.lineTo(e,n),t.lineTo(s,n),t.lineTo(s,this.base),t.fill(),this.showStroke&&t.stroke()},height:function(){return this.base-this.y},inRange:function(t,i){return t>=this.x-this.width/2&&t<=this.x+this.width/2&&i>=this.y&&i<=this.base}}),e.Tooltip=e.Element.extend({draw:function(){var t=this.chart.ctx;t.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.xAlign="center",this.yAlign="above";var i=this.caretPadding=2,e=t.measureText(this.text).width+2*this.xPadding,s=this.fontSize+2*this.yPadding,n=s+this.caretHeight+i;this.x+e/2>this.chart.width?this.xAlign="left":this.x-e/2<0&&(this.xAlign="right"),this.y-n<0&&(this.yAlign="below");var o=this.x-e/2,a=this.y-n;if(t.fillStyle=this.fillColor,this.custom)this.custom(this);else{switch(this.yAlign){case"above":t.beginPath(),t.moveTo(this.x,this.y-i),t.lineTo(this.x+this.caretHeight,this.y-(i+this.caretHeight)),t.lineTo(this.x-this.caretHeight,this.y-(i+this.caretHeight)),t.closePath(),t.fill();break;case"below":a=this.y+i+this.caretHeight,t.beginPath(),t.moveTo(this.x,this.y+i),t.lineTo(this.x+this.caretHeight,this.y+i+this.caretHeight),t.lineTo(this.x-this.caretHeight,this.y+i+this.caretHeight),t.closePath(),t.fill()}switch(this.xAlign){case"left":o=this.x-e+(this.cornerRadius+this.caretHeight);break;case"right":o=this.x-(this.cornerRadius+this.caretHeight)}B(t,o,a,e,s,this.cornerRadius),t.fill(),t.fillStyle=this.textColor,t.textAlign="center",t.textBaseline="middle",t.fillText(this.text,o+e/2,a+s/2)}}}),e.MultiTooltip=e.Element.extend({initialize:function(){this.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.titleFont=W(this.titleFontSize,this.titleFontStyle,this.titleFontFamily),this.height=this.labels.length*this.fontSize+(this.labels.length-1)*(this.fontSize/2)+2*this.yPadding+1.5*this.titleFontSize,this.ctx.font=this.titleFont;var t=this.ctx.measureText(this.title).width,i=z(this.ctx,this.font,this.labels)+this.fontSize+3,e=g([i,t]);this.width=e+2*this.xPadding;var s=this.height/2;this.y-s<0?this.y=s:this.y+s>this.chart.height&&(this.y=this.chart.height-s),this.x>this.chart.width/2?this.x-=this.xOffset+this.width:this.x+=this.xOffset},getLineHeight:function(t){var i=this.y-this.height/2+this.yPadding,e=t-1;return 0===t?i+this.titleFontSize/2:i+(1.5*this.fontSize*e+this.fontSize/2)+1.5*this.titleFontSize},draw:function(){if(this.custom)this.custom(this);else{B(this.ctx,this.x,this.y-this.height/2,this.width,this.height,this.cornerRadius);var t=this.ctx;t.fillStyle=this.fillColor,t.fill(),t.closePath(),t.textAlign="left",t.textBaseline="middle",t.fillStyle=this.titleTextColor,t.font=this.titleFont,t.fillText(this.title,this.x+this.xPadding,this.getLineHeight(0)),t.font=this.font,s.each(this.labels,function(i,e){t.fillStyle=this.textColor,t.fillText(i,this.x+this.xPadding+this.fontSize+3,this.getLineHeight(e+1)),t.fillStyle=this.legendColorBackground,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize),t.fillStyle=this.legendColors[e].fill,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize)},this)}}}),e.Scale=e.Element.extend({initialize:function(){this.fit()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}));this.yLabelWidth=this.display&&this.showLabels?z(this.ctx,this.font,this.yLabels):0},addXLabel:function(t){this.xLabels.push(t),this.valuesCount++,this.fit()},removeXLabel:function(){this.xLabels.shift(),this.valuesCount--,this.fit()},fit:function(){this.startPoint=this.display?this.fontSize:0,this.endPoint=this.display?this.height-1.5*this.fontSize-5:this.height,this.startPoint+=this.padding,this.endPoint-=this.padding;var t,i=this.endPoint-this.startPoint;for(this.calculateYRange(i),this.buildYLabels(),this.calculateXLabelRotation();i>this.endPoint-this.startPoint;)i=this.endPoint-this.startPoint,t=this.yLabelWidth,this.calculateYRange(i),this.buildYLabels(),tthis.yLabelWidth+10?e/2:this.yLabelWidth+10,this.xLabelRotation=0,this.display){var n,o=z(this.ctx,this.font,this.xLabels);this.xLabelWidth=o;for(var a=Math.floor(this.calculateX(1)-this.calculateX(0))-6;this.xLabelWidth>a&&0===this.xLabelRotation||this.xLabelWidth>a&&this.xLabelRotation<=90&&this.xLabelRotation>0;)n=Math.cos(S(this.xLabelRotation)),t=n*e,i=n*s,t+this.fontSize/2>this.yLabelWidth+8&&(this.xScalePaddingLeft=t+this.fontSize/2),this.xScalePaddingRight=this.fontSize/2,this.xLabelRotation++,this.xLabelWidth=n*o;this.xLabelRotation>0&&(this.endPoint-=Math.sin(S(this.xLabelRotation))*o+3)}else this.xLabelWidth=0,this.xScalePaddingRight=this.padding,this.xScalePaddingLeft=this.padding},calculateYRange:c,drawingArea:function(){return this.startPoint-this.endPoint},calculateY:function(t){var i=this.drawingArea()/(this.min-this.max);return this.endPoint-i*(t-this.min)},calculateX:function(t){var i=(this.xLabelRotation>0,this.width-(this.xScalePaddingLeft+this.xScalePaddingRight)),e=i/Math.max(this.valuesCount-(this.offsetGridLines?0:1),1),s=e*t+this.xScalePaddingLeft;return this.offsetGridLines&&(s+=e/2),Math.round(s)},update:function(t){s.extend(this,t),this.fit()},draw:function(){var t=this.ctx,i=(this.endPoint-this.startPoint)/this.steps,e=Math.round(this.xScalePaddingLeft);this.display&&(t.fillStyle=this.textColor,t.font=this.font,n(this.yLabels,function(n,o){var a=this.endPoint-i*o,h=Math.round(a),l=this.showHorizontalLines;t.textAlign="right",t.textBaseline="middle",this.showLabels&&t.fillText(n,e-10,a),0!==o||l||(l=!0),l&&t.beginPath(),o>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),h+=s.aliasPixel(t.lineWidth),l&&(t.moveTo(e,h),t.lineTo(this.width,h),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(e-5,h),t.lineTo(e,h),t.stroke(),t.closePath()},this),n(this.xLabels,function(i,e){var s=this.calculateX(e)+x(this.lineWidth),n=this.calculateX(e-(this.offsetGridLines?.5:0))+x(this.lineWidth),o=this.xLabelRotation>0,a=this.showVerticalLines;0!==e||a||(a=!0),a&&t.beginPath(),e>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),a&&(t.moveTo(n,this.endPoint),t.lineTo(n,this.startPoint-3),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(n,this.endPoint),t.lineTo(n,this.endPoint+5),t.stroke(),t.closePath(),t.save(),t.translate(s,o?this.endPoint+12:this.endPoint+8),t.rotate(-1*S(this.xLabelRotation)),t.font=this.font,t.textAlign=o?"right":"center",t.textBaseline=o?"middle":"top",t.fillText(i,0,0),t.restore()},this))}}),e.RadialScale=e.Element.extend({initialize:function(){this.size=m([this.height,this.width]),this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2},calculateCenterOffset:function(t){var i=this.drawingArea/(this.max-this.min);return(t-this.min)*i},update:function(){this.lineArc?this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2:this.setScaleSize(),this.buildYLabels()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}))},getCircumference:function(){return 2*Math.PI/this.valuesCount},setScaleSize:function(){var t,i,e,s,n,o,a,h,l,r,c,u,d=m([this.height/2-this.pointLabelFontSize-5,this.width/2]),p=this.width,g=0;for(this.ctx.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),i=0;ip&&(p=t.x+s,n=i),t.x-sp&&(p=t.x+e,n=i):i>this.valuesCount/2&&t.x-e0){var s,n=e*(this.drawingArea/this.steps),o=this.yCenter-n;if(this.lineWidth>0)if(t.strokeStyle=this.lineColor,t.lineWidth=this.lineWidth,this.lineArc)t.beginPath(),t.arc(this.xCenter,this.yCenter,n,0,2*Math.PI),t.closePath(),t.stroke();else{t.beginPath();for(var a=0;a=0;i--){if(this.angleLineWidth>0){var e=this.getPointPosition(i,this.calculateCenterOffset(this.max));t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(e.x,e.y),t.stroke(),t.closePath()}var s=this.getPointPosition(i,this.calculateCenterOffset(this.max)+5);t.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),t.fillStyle=this.pointLabelFontColor;var o=this.labels.length,a=this.labels.length/2,h=a/2,l=h>i||i>o-h,r=i===h||i===o-h;t.textAlign=0===i?"center":i===a?"center":a>i?"left":"right",t.textBaseline=r?"middle":l?"bottom":"top",t.fillText(this.labels[i],s.x,s.y)}}}}}),s.addEvent(window,"resize",function(){var t;return function(){clearTimeout(t),t=setTimeout(function(){n(e.instances,function(t){t.options.responsive&&t.resize(t.render,!0)})},50)}}()),p?define(function(){return e}):"object"==typeof module&&module.exports&&(module.exports=e),t.Chart=e,e.noConflict=function(){return t.Chart=i,e}}).call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleBeginAtZero:!0,scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,scaleShowHorizontalLines:!0,scaleShowVerticalLines:!0,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,legendTemplate:'
      <% for (var i=0; i
    • <%if(datasets[i].label){%><%=datasets[i].label%><%}%>
    • <%}%>
    '};i.Type.extend({name:"Bar",defaults:s,initialize:function(t){var s=this.options;this.ScaleClass=i.Scale.extend({offsetGridLines:!0,calculateBarX:function(t,i,e){var n=this.calculateBaseWidth(),o=this.calculateX(e)-n/2,a=this.calculateBarWidth(t);return o+a*i+i*s.barDatasetSpacing+a/2},calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)-2*s.barValueSpacing},calculateBarWidth:function(t){var i=this.calculateBaseWidth()-(t-1)*s.barDatasetSpacing;return i/t}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getBarsAtEvent(t):[];this.eachBars(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),this.BarClass=i.Rectangle.extend({strokeWidth:this.options.barStrokeWidth,showStroke:this.options.barShowStroke,ctx:this.chart.ctx}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,bars:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.bars.push(new this.BarClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.strokeColor,fillColor:i.fillColor,highlightFill:i.highlightFill||i.fillColor,highlightStroke:i.highlightStroke||i.strokeColor}))},this)},this),this.buildScale(t.labels),this.BarClass.prototype.base=this.scale.endPoint,this.eachBars(function(t,i,s){e.extend(t,{width:this.scale.calculateBarWidth(this.datasets.length),x:this.scale.calculateBarX(this.datasets.length,s,i),y:this.scale.endPoint}),t.save()},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachBars(function(t){t.save()}),this.render()},eachBars:function(t){e.each(this.datasets,function(i,s){e.each(i.bars,t,this,s)},this)},getBarsAtEvent:function(t){for(var i,s=[],n=e.getRelativePosition(t),o=function(t){s.push(t.bars[i])},a=0;a<% for (var i=0; i
  • <%if(segments[i].label){%><%=segments[i].label%><%}%>
  • <%}%>'};i.Type.extend({name:"Doughnut",defaults:s,initialize:function(t){this.segments=[],this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,this.SegmentArc=i.Arc.extend({ctx:this.chart.ctx,x:this.chart.width/2,y:this.chart.height/2}),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.calculateTotal(t),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({value:t.value,outerRadius:this.options.animateScale?0:this.outerRadius,innerRadius:this.options.animateScale?0:this.outerRadius/100*this.options.percentageInnerCutout,fillColor:t.color,highlightColor:t.highlight||t.color,showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,startAngle:1.5*Math.PI,circumference:this.options.animateRotate?0:this.calculateCircumference(t.value),label:t.label})),e||(this.reflow(),this.update())},calculateCircumference:function(t){return 2*Math.PI*(Math.abs(t)/this.total)},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=Math.abs(t.value)},this)},update:function(){this.calculateTotal(this.segments),e.each(this.activeElements,function(t){t.restore(["fillColor"])}),e.each(this.segments,function(t){t.save()}),this.render()},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,e.each(this.segments,function(t){t.update({outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout})},this)},draw:function(t){var i=t?t:1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.calculateCircumference(t.value),outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout},i),t.endAngle=t.startAngle+t.circumference,t.draw(),0===e&&(t.startAngle=1.5*Math.PI),e<% for (var i=0; i
  • <%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>'};i.Type.extend({name:"Line",defaults:s,initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx,inRange:function(t){return Math.pow(t-this.x,2)0&&ithis.scale.endPoint?t.controlPoints.outer.y=this.scale.endPoint:t.controlPoints.outer.ythis.scale.endPoint?t.controlPoints.inner.y=this.scale.endPoint:t.controlPoints.inner.y0&&(s.lineTo(h[h.length-1].x,this.scale.endPoint),s.lineTo(h[0].x,this.scale.endPoint),s.fillStyle=t.fillColor,s.closePath(),s.fill()),e.each(h,function(t){t.draw()})},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBeginAtZero:!0,scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,scaleShowLine:!0,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'
      <% for (var i=0; i
    • <%if(segments[i].label){%><%=segments[i].label%><%}%>
    • <%}%>
    '};i.Type.extend({name:"PolarArea",defaults:s,initialize:function(t){this.segments=[],this.SegmentArc=i.Arc.extend({showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,ctx:this.chart.ctx,innerRadius:0,x:this.chart.width/2,y:this.chart.height/2}),this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,lineArc:!0,width:this.chart.width,height:this.chart.height,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,valuesCount:t.length}),this.updateScaleRange(t),this.scale.update(),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({fillColor:t.color,highlightColor:t.highlight||t.color,label:t.label,value:t.value,outerRadius:this.options.animateScale?0:this.scale.calculateCenterOffset(t.value),circumference:this.options.animateRotate?0:this.scale.getCircumference(),startAngle:1.5*Math.PI})),e||(this.reflow(),this.update())},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=t.value},this),this.scale.valuesCount=this.segments.length},updateScaleRange:function(t){var i=[];e.each(t,function(t){i.push(t.value)});var s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s,{size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2})},update:function(){this.calculateTotal(this.segments),e.each(this.segments,function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.updateScaleRange(this.segments),this.scale.update(),e.extend(this.scale,{xCenter:this.chart.width/2,yCenter:this.chart.height/2}),e.each(this.segments,function(t){t.update({outerRadius:this.scale.calculateCenterOffset(t.value)})},this)},draw:function(t){var i=t||1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.scale.getCircumference(),outerRadius:this.scale.calculateCenterOffset(t.value)},i),t.endAngle=t.startAngle+t.circumference,0===e&&(t.startAngle=1.5*Math.PI),e<% for (var i=0; i
  • <%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>'},initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx}),this.datasets=[],this.buildScale(t),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){var o;this.scale.animation||(o=this.scale.getPointPosition(n,this.scale.calculateCenterOffset(e))),s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,x:this.options.animation?this.scale.xCenter:o.x,y:this.options.animation?this.scale.yCenter:o.y,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this)},this),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=e.getRelativePosition(t),s=e.getAngleFromPoint({x:this.scale.xCenter,y:this.scale.yCenter},i),n=2*Math.PI/this.scale.valuesCount,o=Math.round((s.angle-1.5*Math.PI)/n),a=[];return(o>=this.scale.valuesCount||0>o)&&(o=0),s.distance<=this.scale.drawingArea&&e.each(this.datasets,function(t){a.push(t.points[o])}),a},buildScale:function(t){this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,angleLineColor:this.options.angleLineColor,angleLineWidth:this.options.angleShowLineOut?this.options.angleLineWidth:0,pointLabelFontColor:this.options.pointLabelFontColor,pointLabelFontSize:this.options.pointLabelFontSize,pointLabelFontFamily:this.options.pointLabelFontFamily,pointLabelFontStyle:this.options.pointLabelFontStyle,height:this.chart.height,width:this.chart.width,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,labels:t.labels,valuesCount:t.datasets[0].data.length}),this.scale.setScaleSize(),this.updateScaleRange(t.datasets),this.scale.buildYLabels()},updateScaleRange:function(t){var i=function(){var i=[];return e.each(t,function(t){t.data?i=i.concat(t.data):e.each(t.points,function(t){i.push(t.value)})}),i}(),s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s)},addData:function(t,i){this.scale.valuesCount++,e.each(t,function(t,e){var s=this.scale.getPointPosition(this.scale.valuesCount,this.scale.calculateCenterOffset(t));this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:s.x,y:s.y,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.labels.push(i),this.reflow(),this.update()},removeData:function(){this.scale.valuesCount--,this.scale.labels.shift(),e.each(this.datasets,function(t){t.points.shift()},this),this.reflow(),this.update()},update:function(){this.eachPoints(function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.scale,{width:this.chart.width,height:this.chart.height,size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2}),this.updateScaleRange(this.datasets),this.scale.setScaleSize(),this.scale.buildYLabels()},draw:function(t){var i=t||1,s=this.chart.ctx;this.clear(),this.scale.draw(),e.each(this.datasets,function(t){e.each(t.points,function(t,e){t.hasValue()&&t.transition(this.scale.getPointPosition(e,this.scale.calculateCenterOffset(t.value)),i)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(t.points,function(t,i){0===i?s.moveTo(t.x,t.y):s.lineTo(t.x,t.y)},this),s.closePath(),s.stroke(),s.fillStyle=t.fillColor,s.fill(),e.each(t.points,function(t){t.hasValue()&&t.draw()})},this)}})}.call(this); \ No newline at end of file diff --git a/vendor/assets/javascripts/g.bar-min.js b/vendor/assets/javascripts/g.bar-min.js deleted file mode 100644 index 7620dabda74366adba1c781d313a4bd26bdcc6c9..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/g.bar-min.js +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * g.Raphael 0.5 - Charting library, based on Raphaël - * - * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com) - * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. - * From: https://github.com/jhurt/g.raphael/blob/master/g.bar.js - */ -(function(){function c(c,d,e,f,g,h,i,j){var k,l={round:"round",sharp:"sharp",soft:"soft",square:"square"};if(g&&!f||!g&&!e)return i?"":j.path();switch(h=l[h]||"square",f=Math.round(f),e=Math.round(e),c=Math.round(c),d=Math.round(d),h){case"round":if(g)m=~~(e/2),m>f?(m=f,k=["M",c-~~(e/2),d,"l",0,0,"a",~~(e/2),m,0,0,1,e,0,"l",0,0,"z"]):k=["M",c-m,d,"l",0,m-f,"a",m,m,0,1,1,e,0,"l",0,f-m,"z"];else{var m=~~(f/2);m>e?(m=e,k=["M",c+.5,d+.5-~~(f/2),"l",0,0,"a",m,~~(f/2),0,0,1,0,f,"l",0,0,"z"]):k=["M",c+.5,d+.5-m,"l",e-m,0,"a",m,m,0,1,1,0,f,"l",m-e,0,"z"]}break;case"sharp":if(g)n=~~(e/2),k=["M",c+n,d,"l",-e,0,0,-b(f-n,0),n,-a(n,f),n,a(n,f),n,"z"];else{var n=~~(f/2);k=["M",c,d+n,"l",0,-f,b(e-n,0),0,a(n,e),n,-a(n,e),n+(f>2*n),"z"]}break;case"square":k=g?["M",c+~~(e/2),d,"l",1-e,0,0,-f,e-1,0,"z"]:["M",c,d+~~(f/2),"l",0,-f,e,0,0,f,"z"];break;case"soft":g?(m=a(Math.round(e/5),f),k=["M",c-~~(e/2),d,"l",0,m-f,"a",m,m,0,0,1,m,-m,"l",e-2*m,0,"a",m,m,0,0,1,m,m,"l",0,f-m,"z"]):(m=a(e,Math.round(f/5)),k=["M",c+.5,d+.5-~~(f/2),"l",e-m,0,"a",m,m,0,0,1,m,m,"l",0,f-2*m,"a",m,m,0,0,1,-m,m,"l",m-e,0,"z"])}return i?k.join(","):j.path(k)}function d(a,b,d,e,f,g,h){h=h||{};var i=this,j=h.type||"square",k=parseFloat(h.gutter||"20%"),l=a.set(),m=a.set(),n=a.set(),o=a.set(),p=Math.max.apply(Math,g),q=[],r=0,s=h.colors||i.colors,t=g.length;if(Raphael.is(g[0],"array")){p=[],r=t,t=0;for(var u=g.length;u--;)m.push(a.set()),p.push(Math.max.apply(Math,g[u])),t=Math.max(t,g[u].length);if(h.stacked)for(var u=t;u--;){for(var v=0,w=g.length;w--;)v+=+g[w][u]||0;q.push(v)}for(var u=g.length;u--;)if(t>g[u].length)for(var w=t;w--;)g[u].push(0);p=Math.max.apply(Math,h.stacked?q:p)}p=h.to||p;var x=100*(e/(t*(100+k)+k)),y=x*k/100,z=null==h.vgutter?20:h.vgutter,A=[],B=b+y,C=(f-2*z)/p;h.stretch||(y=Math.round(y),x=Math.floor(x)),!h.stacked&&(x/=r||1);for(var u=0;t>u;u++){A=[];for(var w=0;(r||1)>w;w++){var D=Math.round((r?g[w][u]:g[u])*C),E=d+f-z-D,F=c(Math.round(B+x/2),E+D,x,D,!0,j,null,a).attr({stroke:"none",fill:s[r?w:u]});r?m[w].push(F):m.push(F),F.y=E,F.x=Math.round(B+x/2),F.w=x,F.h=D,F.value=r?g[w][u]:g[u],h.stacked?A.push(F):B+=x}if(h.stacked){var G;o.push(G=a.rect(A[0].x-A[0].w/2,d,x,f).attr(i.shim)),G.bars=a.set();for(var H=0,I=A.length;I--;)A[I].toFront();for(var I=0,J=A.length;J>I;I++){var K,F=A[I],D=(H+F.value)*C,L=c(F.x,d+f-z-.5*!!H,x,D,!0,j,1,a);G.bars.push(F),H&&F.attr({path:L}),F.h=D,F.y=d+f-z-.5*!!H-D,n.push(K=a.rect(F.x-F.w/2,F.y,x,F.value*C).attr(i.shim)),K.bar=F,K.value=F.value,H+=F.value}B+=x}B+=y}if(o.toFront(),B=b+y,!h.stacked)for(var u=0;t>u;u++){for(var w=0;(r||1)>w;w++){var K;n.push(K=a.rect(Math.round(B),d+z,x,f-z).attr(i.shim)),K.bar=r?m[w][u]:m[u],K.value=K.bar.value,B+=x}B+=y}return l.label=function(b,c){b=b||[],this.labels=a.set();var e,j=-1/0;if(h.stacked){for(var k=0;t>k;k++)for(var l=0,o=0;(r||1)>o;o++)if(l+=r?g[o][k]:g[k],o==r-1){var q=i.labelise(b[k],l,p);e=a.text(m[o][k].x,d+f-z/2,q).attr(i.txtattr).attr({fill:h.legendcolor||"#000","text-anchor":"start"}).insertBefore(n[k*(r||1)+o]);var s=e.getBBox();j>s.x-7?e.remove():(this.labels.push(e),j=s.x+s.width)}}else for(var k=0;t>k;k++)for(var o=0;(r||1)>o;o++){var q=i.labelise(r?b[o]&&b[o][k]:b[k],r?g[o][k]:g[k],p);e=a.text(m[o][k].x-x/2,c?d+f-z/2:m[o][k].y-10,q).attr(i.txtattr).attr({fill:h.legendcolor||"#000","text-anchor":"start"}).insertBefore(n[k*(r||1)+o]);var s=e.getBBox();e.translate((x-s.width)/2,1),j>s.x-7?e.remove():(this.labels.push(e),j=s.x+s.width)}return this},l.hover=function(a,b){return o.hide(),n.show(),n.mouseover(a).mouseout(b),this},l.hoverColumn=function(a,b){return n.hide(),o.show(),b=b||function(){},o.mouseover(a).mouseout(b),this},l.click=function(a){return o.hide(),n.show(),n.click(a),this},l.each=function(a){if(!Raphael.is(a,"function"))return this;for(var b=n.length;b--;)a.call(n[b]);return this},l.eachColumn=function(a){if(!Raphael.is(a,"function"))return this;for(var b=o.length;b--;)a.call(o[b]);return this},l.clickColumn=function(a){return n.hide(),o.show(),o.click(a),this},l.push(m,n,o),l.bars=m,l.covers=n,l}function e(a,b,d,e,f,g,h){h=h||{};var i=this,j=h.type||"square",k=parseFloat(h.gutter||"20%"),l=a.set(),m=a.set(),n=a.set(),o=a.set(),p=Math.max.apply(Math,g),q=[],r=0,s=h.colors||i.colors,t=g.length;if(Raphael.is(g[0],"array")){p=[],r=t,t=0;for(var u=g.length;u--;)m.push(a.set()),p.push(Math.max.apply(Math,g[u])),t=Math.max(t,g[u].length);if(h.stacked)for(var u=t;u--;){for(var v=0,w=g.length;w--;)v+=+g[w][u]||0;q.push(v)}for(var u=g.length;u--;)if(t>g[u].length)for(var w=t;w--;)g[u].push(0);p=Math.max.apply(Math,h.stacked?q:p)}p=h.to||p;var x=Math.floor(100*(f/(t*(100+k)+k))),y=Math.floor(x*k/100),z=[],A=d+y,B=(e-1)/p;!h.stacked&&(x/=r||1);for(var u=0;t>u;u++){z=[];for(var w=0;(r||1)>w;w++){var C=r?g[w][u]:g[u],D=c(b,A+x/2,Math.round(C*B),x-1,!1,j,null,a).attr({stroke:"none",fill:s[r?w:u]});r?m[w].push(D):m.push(D),D.x=b+Math.round(C*B),D.y=A+x/2,D.w=Math.round(C*B),D.h=x,D.value=+C,h.stacked?z.push(D):A+=x}if(h.stacked){var E=a.rect(b,z[0].y-z[0].h/2,e,x).attr(i.shim);o.push(E),E.bars=a.set();for(var F=0,G=z.length;G--;)z[G].toFront();for(var G=0,H=z.length;H>G;G++){var I,D=z[G],C=Math.round((F+D.value)*B),J=c(b,D.y,C,x-1,!1,j,1,a);E.bars.push(D),F&&D.attr({path:J}),D.w=C,D.x=b+C,n.push(I=a.rect(b+F*B,D.y-D.h/2,D.value*B,x).attr(i.shim)),I.bar=D,F+=D.value}A+=x}A+=y}if(o.toFront(),A=d+y,!h.stacked)for(var u=0;t>u;u++){for(var w=0;(r||1)>w;w++){var I=a.rect(b,A,e,x).attr(i.shim);n.push(I),I.bar=r?m[w][u]:m[u],I.value=I.bar.value,A+=x}A+=y}return l.label=function(c,d){c=c||[],this.labels=a.set();for(var e=0;t>e;e++)for(var f=0;r>f;f++){var o,j=i.labelise(r?c[f]&&c[f][e]:c[e],r?g[f][e]:g[e],p),k=d?m[f][e].x-x/2+3:b+5;this.labels.push(o=a.text(k,m[f][e].y,j).attr(i.txtattr).attr({fill:h.legendcolor||"#000","text-anchor":"start"}).insertBefore(n[0])),b+5>o.getBBox().x?o.attr({x:b+5,"text-anchor":"start"}):m[f][e].label=o}return this},l.hover=function(a,b){return o.hide(),n.show(),b=b||function(){},n.mouseover(a).mouseout(b),this},l.hoverColumn=function(a,b){return n.hide(),o.show(),b=b||function(){},o.mouseover(a).mouseout(b),this},l.each=function(a){if(!Raphael.is(a,"function"))return this;for(var b=n.length;b--;)a.call(n[b]);return this},l.eachColumn=function(a){if(!Raphael.is(a,"function"))return this;for(var b=o.length;b--;)a.call(o[b]);return this},l.click=function(a){return o.hide(),n.show(),n.click(a),this},l.clickColumn=function(a){return n.hide(),o.show(),o.click(a),this},l.push(m,n,o),l.bars=m,l.covers=n,l}var a=Math.min,b=Math.max,f=function(){};f.prototype=Raphael.g,e.prototype=d.prototype=new f,Raphael.fn.hbarchart=function(a,b,c,d,f,g){return new e(this,a,b,c,d,f,g)},Raphael.fn.barchart=function(a,b,c,e,f,g){return new d(this,a,b,c,e,f,g)}})(); \ No newline at end of file diff --git a/vendor/assets/javascripts/g.raphael-min.js b/vendor/assets/javascripts/g.raphael-min.js deleted file mode 100644 index f8b381c623bc553a4cefcf930b8bf08078ad4847..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/g.raphael-min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * g.Raphael 0.51 - Charting library, based on Raphaël - * - * Copyright (c) 2009-2012 Dmitry Baranovskiy (http://g.raphaeljs.com) - * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. - */ -Raphael.el.popup=function(a,b,c,d){var f,g,h,i,j,e=this.paper||this[0].paper;if(e){switch(this.type){case"text":case"circle":case"ellipse":h=!0;break;default:h=!1}a=null==a?"up":a,b=b||5,f=this.getBBox(),c="number"==typeof c?c:h?f.x+f.width/2:f.x,d="number"==typeof d?d:h?f.y+f.height/2:f.y,i=Math.max(f.width/2-b,0),j=Math.max(f.height/2-b,0),this.translate(c-f.x-(h?f.width/2:0),d-f.y-(h?f.height/2:0)),f=this.getBBox();var k={up:["M",c,d,"l",-b,-b,-i,0,"a",b,b,0,0,1,-b,-b,"l",0,-f.height,"a",b,b,0,0,1,b,-b,"l",2*b+2*i,0,"a",b,b,0,0,1,b,b,"l",0,f.height,"a",b,b,0,0,1,-b,b,"l",-i,0,"z"].join(","),down:["M",c,d,"l",b,b,i,0,"a",b,b,0,0,1,b,b,"l",0,f.height,"a",b,b,0,0,1,-b,b,"l",-(2*b+2*i),0,"a",b,b,0,0,1,-b,-b,"l",0,-f.height,"a",b,b,0,0,1,b,-b,"l",i,0,"z"].join(","),left:["M",c,d,"l",-b,b,0,j,"a",b,b,0,0,1,-b,b,"l",-f.width,0,"a",b,b,0,0,1,-b,-b,"l",0,-(2*b+2*j),"a",b,b,0,0,1,b,-b,"l",f.width,0,"a",b,b,0,0,1,b,b,"l",0,j,"z"].join(","),right:["M",c,d,"l",b,-b,0,-j,"a",b,b,0,0,1,b,-b,"l",f.width,0,"a",b,b,0,0,1,b,b,"l",0,2*b+2*j,"a",b,b,0,0,1,-b,b,"l",-f.width,0,"a",b,b,0,0,1,-b,-b,"l",0,-j,"z"].join(",")};return g={up:{x:-!h*(f.width/2),y:2*-b-(h?f.height/2:f.height)},down:{x:-!h*(f.width/2),y:2*b+(h?f.height/2:f.height)},left:{x:2*-b-(h?f.width/2:f.width),y:-!h*(f.height/2)},right:{x:2*b+(h?f.width/2:f.width),y:-!h*(f.height/2)}}[a],this.translate(g.x,g.y),e.path(k[a]).attr({fill:"#000",stroke:"none"}).insertBefore(this.node?this:this[0])}},Raphael.el.tag=function(a,b,c,d){var e=3,f=this.paper||this[0].paper;if(f){var i,j,k,g=f.path().attr({fill:"#000",stroke:"#000"}),h=this.getBBox();switch(this.type){case"text":case"circle":case"ellipse":k=!0;break;default:k=!1}return a=a||0,c="number"==typeof c?c:k?h.x+h.width/2:h.x,d="number"==typeof d?d:k?h.y+h.height/2:h.y,b=null==b?5:b,j=.5522*b,h.height>=2*b?g.attr({path:["M",c,d+b,"a",b,b,0,1,1,0,2*-b,b,b,0,1,1,0,2*b,"m",0,2*-b-e,"a",b+e,b+e,0,1,0,0,2*(b+e),"L",c+b+e,d+h.height/2+e,"l",h.width+2*e,0,0,-h.height-2*e,-h.width-2*e,0,"L",c,d-b-e].join(",")}):(i=Math.sqrt(Math.pow(b+e,2)-Math.pow(h.height/2+e,2)),g.attr({path:["M",c,d+b,"c",-j,0,-b,j-b,-b,-b,0,-j,b-j,-b,b,-b,j,0,b,b-j,b,b,0,j,j-b,b,-b,b,"M",c+i,d-h.height/2-e,"a",b+e,b+e,0,1,0,0,h.height+2*e,"l",b+e-i+h.width+2*e,0,0,-h.height-2*e,"L",c+i,d-h.height/2-e].join(",")})),a=360-a,g.rotate(a,c,d),this.attrs?(this.attr(this.attrs.x?"x":"cx",c+b+e+(k?h.width/2:"text"==this.type?h.width:0)).attr("y",k?d:d-h.height/2),this.rotate(a,c,d),a>90&&270>a&&this.attr(this.attrs.x?"x":"cx",c-b-e-(k?h.width/2:h.width)).rotate(180,c,d)):a>90&&270>a?(this.translate(c-h.x-h.width-b-e,d-h.y-h.height/2),this.rotate(a-180,h.x+h.width+b+e,h.y+h.height/2)):(this.translate(c-h.x+b+e,d-h.y-h.height/2),this.rotate(a,h.x-b-e,h.y+h.height/2)),g.insertBefore(this.node?this:this[0])}},Raphael.el.drop=function(a,b,c){var f,g,h,i,j,d=this.getBBox(),e=this.paper||this[0].paper;if(e){switch(this.type){case"text":case"circle":case"ellipse":f=!0;break;default:f=!1}return a=a||0,b="number"==typeof b?b:f?d.x+d.width/2:d.x,c="number"==typeof c?c:f?d.y+d.height/2:d.y,g=Math.max(d.width,d.height)+Math.min(d.width,d.height),h=e.path(["M",b,c,"l",g,0,"A",.4*g,.4*g,0,1,0,b+.7*g,c-.7*g,"z"]).attr({fill:"#000",stroke:"none"}).rotate(22.5-a,b,c),a=(a+90)*Math.PI/180,i=b+g*Math.sin(a)-(f?0:d.width/2),j=c+g*Math.cos(a)-(f?0:d.height/2),this.attrs?this.attr(this.attrs.x?"x":"cx",i).attr(this.attrs.y?"y":"cy",j):this.translate(i-d.x,j-d.y),h.insertBefore(this.node?this:this[0])}},Raphael.el.flag=function(a,b,c){var d=3,e=this.paper||this[0].paper;if(e){var i,f=e.path().attr({fill:"#000",stroke:"#000"}),g=this.getBBox(),h=g.height/2;switch(this.type){case"text":case"circle":case"ellipse":i=!0;break;default:i=!1}return a=a||0,b="number"==typeof b?b:i?g.x+g.width/2:g.x,c="number"==typeof c?c:i?g.y+g.height/2:g.y,f.attr({path:["M",b,c,"l",h+d,-h-d,g.width+2*d,0,0,g.height+2*d,-g.width-2*d,0,"z"].join(",")}),a=360-a,f.rotate(a,b,c),this.attrs?(this.attr(this.attrs.x?"x":"cx",b+h+d+(i?g.width/2:"text"==this.type?g.width:0)).attr("y",i?c:c-g.height/2),this.rotate(a,b,c),a>90&&270>a&&this.attr(this.attrs.x?"x":"cx",b-h-d-(i?g.width/2:g.width)).rotate(180,b,c)):a>90&&270>a?(this.translate(b-g.x-g.width-h-d,c-g.y-g.height/2),this.rotate(a-180,g.x+g.width+h+d,g.y+g.height/2)):(this.translate(b-g.x+h+d,c-g.y-g.height/2),this.rotate(a,g.x-h-d,g.y+g.height/2)),f.insertBefore(this.node?this:this[0])}},Raphael.el.label=function(){var a=this.getBBox(),b=this.paper||this[0].paper,c=Math.min(20,a.width+10,a.height+10)/2;if(b)return b.rect(a.x-c/2,a.y-c/2,a.width+c,a.height+c,c).attr({stroke:"none",fill:"#000"}).insertBefore(this.node?this:this[0])},Raphael.el.blob=function(a,b,c){var g,h,i,d=this.getBBox(),e=Math.PI/180,f=this.paper||this[0].paper;if(f){switch(this.type){case"text":case"circle":case"ellipse":h=!0;break;default:h=!1}g=f.path().attr({fill:"#000",stroke:"none"}),a=(+a+1?a:45)+90,i=Math.min(d.height,d.width),b="number"==typeof b?b:h?d.x+d.width/2:d.x,c="number"==typeof c?c:h?d.y+d.height/2:d.y;var j=Math.max(d.width+i,25*i/12),k=Math.max(d.height+i,25*i/12),l=b+i*Math.sin((a-22.5)*e),m=c+i*Math.cos((a-22.5)*e),n=b+i*Math.sin((a+22.5)*e),o=c+i*Math.cos((a+22.5)*e),p=(n-l)/2,q=(o-m)/2,r=j/2,s=k/2,t=-Math.sqrt(Math.abs(r*r*s*s-r*r*q*q-s*s*p*p)/(r*r*q*q+s*s*p*p)),u=t*r*q/s+(n+l)/2,v=t*-s*p/r+(o+m)/2;return g.attr({x:u,y:v,path:["M",b,c,"L",n,o,"A",r,s,0,1,1,l,m,"z"].join(",")}),this.translate(u-d.x-d.width/2,v-d.y-d.height/2),g.insertBefore(this.node?this:this[0])}},Raphael.fn.label=function(a,b,c){var d=this.set();return c=this.text(a,b,c).attr(Raphael.g.txtattr),d.push(c.label(),c)},Raphael.fn.popup=function(a,b,c,d,e){var f=this.set();return c=this.text(a,b,c).attr(Raphael.g.txtattr),f.push(c.popup(d,e),c)},Raphael.fn.tag=function(a,b,c,d,e){var f=this.set();return c=this.text(a,b,c).attr(Raphael.g.txtattr),f.push(c.tag(d,e),c)},Raphael.fn.flag=function(a,b,c,d){var e=this.set();return c=this.text(a,b,c).attr(Raphael.g.txtattr),e.push(c.flag(d),c)},Raphael.fn.drop=function(a,b,c,d){var e=this.set();return c=this.text(a,b,c).attr(Raphael.g.txtattr),e.push(c.drop(d),c)},Raphael.fn.blob=function(a,b,c,d){var e=this.set();return c=this.text(a,b,c).attr(Raphael.g.txtattr),e.push(c.blob(d),c)},Raphael.el.lighter=function(a){a=a||2;var b=[this.attrs.fill,this.attrs.stroke];return this.fs=this.fs||[b[0],b[1]],b[0]=Raphael.rgb2hsb(Raphael.getRGB(b[0]).hex),b[1]=Raphael.rgb2hsb(Raphael.getRGB(b[1]).hex),b[0].b=Math.min(b[0].b*a,1),b[0].s=b[0].s/a,b[1].b=Math.min(b[1].b*a,1),b[1].s=b[1].s/a,this.attr({fill:"hsb("+[b[0].h,b[0].s,b[0].b]+")",stroke:"hsb("+[b[1].h,b[1].s,b[1].b]+")"}),this},Raphael.el.darker=function(a){a=a||2;var b=[this.attrs.fill,this.attrs.stroke];return this.fs=this.fs||[b[0],b[1]],b[0]=Raphael.rgb2hsb(Raphael.getRGB(b[0]).hex),b[1]=Raphael.rgb2hsb(Raphael.getRGB(b[1]).hex),b[0].s=Math.min(b[0].s*a,1),b[0].b=b[0].b/a,b[1].s=Math.min(b[1].s*a,1),b[1].b=b[1].b/a,this.attr({fill:"hsb("+[b[0].h,b[0].s,b[0].b]+")",stroke:"hsb("+[b[1].h,b[1].s,b[1].b]+")"}),this},Raphael.el.resetBrightness=function(){return this.fs&&(this.attr({fill:this.fs[0],stroke:this.fs[1]}),delete this.fs),this},function(){var a=["lighter","darker","resetBrightness"],b=["popup","tag","flag","label","drop","blob"];for(var c in b)(function(a){Raphael.st[a]=function(){return Raphael.el[a].apply(this,arguments)}})(b[c]);for(var c in a)(function(a){Raphael.st[a]=function(){for(var b=0;this.length>b;b++)this[b][a].apply(this[b],arguments);return this}})(a[c])}(),Raphael.g={shim:{stroke:"none",fill:"#000","fill-opacity":0},txtattr:{font:"12px Arial, sans-serif",fill:"#fff"},colors:function(){for(var a=[.6,.2,.05,.1333,.75,0],b=[],c=0;10>c;c++)a.length>c?b.push("hsb("+a[c]+",.75, .75)"):b.push("hsb("+a[c-a.length]+", 1, .5)");return b}(),snapEnds:function(a,b,c){function f(a){return.25>Math.abs(a-.5)?~~a+.5:Math.round(a)}var d=a,e=b;if(d==e)return{from:d,to:e,power:0};var g=(e-d)/c,h=~~g,i=h,j=0;if(h){for(;i;)j--,i=~~(g*Math.pow(10,j))/Math.pow(10,j);j++}else{if(0!=g&&isFinite(g))for(;!h;)j=j||1,h=~~(g*Math.pow(10,j))/Math.pow(10,j),j++;else j=1;j&&j--}return e=f(b*Math.pow(10,j))/Math.pow(10,j),b>e&&(e=f((b+.5)*Math.pow(10,j))/Math.pow(10,j)),d=f((a-(j>0?0:.5))*Math.pow(10,j))/Math.pow(10,j),{from:d,to:e,power:j}},axis:function(a,b,c,d,e,f,g,h,i,j,k){j=null==j?2:j,i=i||"t",f=f||10,k=arguments[arguments.length-1];var t,l="|"==i||" "==i?["M",a+.5,b,"l",0,.001]:1==g||3==g?["M",a+.5,b,"l",0,-c]:["M",a,b+.5,"l",c,0],m=this.snapEnds(d,e,f),n=m.from,o=m.to,p=m.power,q=0,r={font:"11px 'Fontin Sans', Fontin-Sans, sans-serif"},s=k.set();t=(o-n)/f;var u=n,v=p>0?p:0;if(z=c/f,1==+g||3==+g){for(var w=b,x=(g-1?1:-1)*(j+3+!!(g-1));w>=b-c;)"-"!=i&&" "!=i&&(l=l.concat(["M",a-("+"==i||"|"==i?j:2*!(g-1)*j),w+.5,"l",2*j+1,0])),s.push(k.text(a+x,w,h&&h[q++]||(Math.round(u)==u?u:+u.toFixed(v))).attr(r).attr({"text-anchor":g-1?"start":"end"})),u+=t,w-=z;Math.round(w+z-(b-c))&&("-"!=i&&" "!=i&&(l=l.concat(["M",a-("+"==i||"|"==i?j:2*!(g-1)*j),b-c+.5,"l",2*j+1,0])),s.push(k.text(a+x,b-c,h&&h[q]||(Math.round(u)==u?u:+u.toFixed(v))).attr(r).attr({"text-anchor":g-1?"start":"end"})))}else{u=n,v=(p>0)*p,x=(g?-1:1)*(j+9+!g);for(var y=a,z=c/f,A=0,B=0;a+c>=y;){"-"!=i&&" "!=i&&(l=l.concat(["M",y+.5,b-("+"==i?j:2*!!g*j),"l",0,2*j+1])),s.push(A=k.text(y,b+x,h&&h[q++]||(Math.round(u)==u?u:+u.toFixed(v))).attr(r));var C=A.getBBox();B>=C.x-5?s.pop(s.length-1).remove():B=C.x+C.width,u+=t,y+=z}Math.round(y-z-a-c)&&("-"!=i&&" "!=i&&(l=l.concat(["M",a+c+.5,b-("+"==i?j:2*!!g*j),"l",0,2*j+1])),s.push(k.text(a+c,b+x,h&&h[q]||(Math.round(u)==u?u:+u.toFixed(v))).attr(r)))}var D=k.path(l);return D.text=s,D.all=k.set([D,s]),D.remove=function(){this.text.remove(),this.constructor.prototype.remove.call(this)},D},labelise:function(a,b,c){return a?(a+"").replace(/(##+(?:\.#+)?)|(%%+(?:\.%+)?)/g,function(a,d,e){return d?(+b).toFixed(d.replace(/^#+\.?/g,"").length):e?(100*b/c).toFixed(e.replace(/^%+\.?/g,"").length)+"%":void 0}):(+b).toFixed(0)}}; \ No newline at end of file diff --git a/vendor/assets/javascripts/jquery.blockUI.js b/vendor/assets/javascripts/jquery.blockUI.js deleted file mode 100644 index c8702d79b654f81ef1ee5039a824dd7f1021e14b..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/jquery.blockUI.js +++ /dev/null @@ -1,590 +0,0 @@ -/*! - * jQuery blockUI plugin - * Version 2.60.0-2013.04.05 - * @requires jQuery v1.7 or later - * - * Examples at: http://malsup.com/jquery/block/ - * Copyright (c) 2007-2013 M. Alsup - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - * Thanks to Amir-Hossein Sobhi for some excellent contributions! - */ - -;(function() { -/*jshint eqeqeq:false curly:false latedef:false */ -"use strict"; - - function setup($) { - $.fn._fadeIn = $.fn.fadeIn; - - var noOp = $.noop || function() {}; - - // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle - // retarded userAgent strings on Vista) - var msie = /MSIE/.test(navigator.userAgent); - var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent); - var mode = document.documentMode || 0; - var setExpr = $.isFunction( document.createElement('div').style.setExpression ); - - // global $ methods for blocking/unblocking the entire page - $.blockUI = function(opts) { install(window, opts); }; - $.unblockUI = function(opts) { remove(window, opts); }; - - // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl) - $.growlUI = function(title, message, timeout, onClose) { - var $m = $('
    '); - if (title) $m.append('

    '+title+'

    '); - if (message) $m.append('

    '+message+'

    '); - if (timeout === undefined) timeout = 3000; - $.blockUI({ - message: $m, fadeIn: 700, fadeOut: 1000, centerY: false, - timeout: timeout, showOverlay: false, - onUnblock: onClose, - css: $.blockUI.defaults.growlCSS - }); - }; - - // plugin method for blocking element content - $.fn.block = function(opts) { - if ( this[0] === window ) { - $.blockUI( opts ); - return this; - } - var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); - this.each(function() { - var $el = $(this); - if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) - return; - $el.unblock({ fadeOut: 0 }); - }); - - return this.each(function() { - if ($.css(this,'position') == 'static') { - this.style.position = 'relative'; - $(this).data('blockUI.static', true); - } - this.style.zoom = 1; // force 'hasLayout' in ie - install(this, opts); - }); - }; - - // plugin method for unblocking element content - $.fn.unblock = function(opts) { - if ( this[0] === window ) { - $.unblockUI( opts ); - return this; - } - return this.each(function() { - remove(this, opts); - }); - }; - - $.blockUI.version = 2.60; // 2nd generation blocking at no extra cost! - - // override these in your code to change the default behavior and style - $.blockUI.defaults = { - // message displayed when blocking (use null for no message) - message: '

    Please wait...

    ', - - title: null, // title string; only used when theme == true - draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) - - theme: false, // set to true to use with jQuery UI themes - - // styles for the message when blocking; if you wish to disable - // these and use an external stylesheet then do this in your code: - // $.blockUI.defaults.css = {}; - css: { - padding: 0, - margin: 0, - width: '30%', - top: '40%', - left: '35%', - textAlign: 'center', - color: '#000', - border: '3px solid #aaa', - backgroundColor:'#fff', - cursor: 'wait' - }, - - // minimal style set used when themes are used - themedCSS: { - width: '30%', - top: '40%', - left: '35%' - }, - - // styles for the overlay - overlayCSS: { - backgroundColor: '#000', - opacity: 0.6, - cursor: 'wait' - }, - - // style to replace wait cursor before unblocking to correct issue - // of lingering wait cursor - cursorReset: 'default', - - // styles applied when using $.growlUI - growlCSS: { - width: '350px', - top: '10px', - left: '', - right: '10px', - border: 'none', - padding: '5px', - opacity: 0.6, - cursor: 'default', - color: '#fff', - backgroundColor: '#000', - '-webkit-border-radius':'10px', - '-moz-border-radius': '10px', - 'border-radius': '10px' - }, - - // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w - // (hat tip to Jorge H. N. de Vasconcelos) - /*jshint scripturl:true */ - iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', - - // force usage of iframe in non-IE browsers (handy for blocking applets) - forceIframe: false, - - // z-index for the blocking overlay - baseZ: 1000, - - // set these to true to have the message automatically centered - centerX: true, // <-- only effects element blocking (page block controlled via css above) - centerY: true, - - // allow body element to be stetched in ie6; this makes blocking look better - // on "short" pages. disable if you wish to prevent changes to the body height - allowBodyStretch: true, - - // enable if you want key and mouse events to be disabled for content that is blocked - bindEvents: true, - - // be default blockUI will supress tab navigation from leaving blocking content - // (if bindEvents is true) - constrainTabKey: true, - - // fadeIn time in millis; set to 0 to disable fadeIn on block - fadeIn: 200, - - // fadeOut time in millis; set to 0 to disable fadeOut on unblock - fadeOut: 400, - - // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock - timeout: 0, - - // disable if you don't want to show the overlay - showOverlay: true, - - // if true, focus will be placed in the first available input field when - // page blocking - focusInput: true, - - // elements that can receive focus - focusableElements: ':input:enabled:visible', - - // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) - // no longer needed in 2012 - // applyPlatformOpacityRules: true, - - // callback method invoked when fadeIn has completed and blocking message is visible - onBlock: null, - - // callback method invoked when unblocking has completed; the callback is - // passed the element that has been unblocked (which is the window object for page - // blocks) and the options that were passed to the unblock call: - // onUnblock(element, options) - onUnblock: null, - - // callback method invoked when the overlay area is clicked. - // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. - onOverlayClick: null, - - // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 - quirksmodeOffsetHack: 4, - - // class name of the message block - blockMsgClass: 'blockMsg', - - // if it is already blocked, then ignore it (don't unblock and reblock) - ignoreIfBlocked: false - }; - - // private data and functions follow... - - var pageBlock = null; - var pageBlockEls = []; - - function install(el, opts) { - var css, themedCSS; - var full = (el == window); - var msg = (opts && opts.message !== undefined ? opts.message : undefined); - opts = $.extend({}, $.blockUI.defaults, opts || {}); - - if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) - return; - - opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); - css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); - if (opts.onOverlayClick) - opts.overlayCSS.cursor = 'pointer'; - - themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); - msg = msg === undefined ? opts.message : msg; - - // remove the current block (if there is one) - if (full && pageBlock) - remove(window, {fadeOut:0}); - - // if an existing element is being used as the blocking content then we capture - // its current place in the DOM (and current display style) so we can restore - // it when we unblock - if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { - var node = msg.jquery ? msg[0] : msg; - var data = {}; - $(el).data('blockUI.history', data); - data.el = node; - data.parent = node.parentNode; - data.display = node.style.display; - data.position = node.style.position; - if (data.parent) - data.parent.removeChild(node); - } - - $(el).data('blockUI.onUnblock', opts.onUnblock); - var z = opts.baseZ; - - // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; - // layer1 is the iframe layer which is used to supress bleed through of underlying content - // layer2 is the overlay layer which has opacity and a wait cursor (by default) - // layer3 is the message content that is displayed while blocking - var lyr1, lyr2, lyr3, s; - if (msie || opts.forceIframe) - lyr1 = $(''); - else - lyr1 = $(''); - - if (opts.theme) - lyr2 = $(''); - else - lyr2 = $(''); - - if (opts.theme && full) { - s = ''; - } - else if (opts.theme) { - s = ''; - } - else if (full) { - s = ''; - } - else { - s = ''; - } - lyr3 = $(s); - - // if we have a message, style it - if (msg) { - if (opts.theme) { - lyr3.css(themedCSS); - lyr3.addClass('ui-widget-content'); - } - else - lyr3.css(css); - } - - // style the overlay - if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) - lyr2.css(opts.overlayCSS); - lyr2.css('position', full ? 'fixed' : 'absolute'); - - // make iframe layer transparent in IE - if (msie || opts.forceIframe) - lyr1.css('opacity',0.0); - - //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); - var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); - $.each(layers, function() { - this.appendTo($par); - }); - - if (opts.theme && opts.draggable && $.fn.draggable) { - lyr3.draggable({ - handle: '.ui-dialog-titlebar', - cancel: 'li' - }); - } - - // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) - var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0); - if (ie6 || expr) { - // give body 100% height - if (full && opts.allowBodyStretch && $.support.boxModel) - $('html,body').css('height','100%'); - - // fix ie6 issue when blocked element has a border width - if ((ie6 || !$.support.boxModel) && !full) { - var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); - var fixT = t ? '(0 - '+t+')' : 0; - var fixL = l ? '(0 - '+l+')' : 0; - } - - // simulate fixed position - $.each(layers, function(i,o) { - var s = o[0].style; - s.position = 'absolute'; - if (i < 2) { - if (full) - s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'); - else - s.setExpression('height','this.parentNode.offsetHeight + "px"'); - if (full) - s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'); - else - s.setExpression('width','this.parentNode.offsetWidth + "px"'); - if (fixL) s.setExpression('left', fixL); - if (fixT) s.setExpression('top', fixT); - } - else if (opts.centerY) { - if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); - s.marginTop = 0; - } - else if (!opts.centerY && full) { - var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; - var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; - s.setExpression('top',expression); - } - }); - } - - // show the message - if (msg) { - if (opts.theme) - lyr3.find('.ui-widget-content').append(msg); - else - lyr3.append(msg); - if (msg.jquery || msg.nodeType) - $(msg).show(); - } - - if ((msie || opts.forceIframe) && opts.showOverlay) - lyr1.show(); // opacity is zero - if (opts.fadeIn) { - var cb = opts.onBlock ? opts.onBlock : noOp; - var cb1 = (opts.showOverlay && !msg) ? cb : noOp; - var cb2 = msg ? cb : noOp; - if (opts.showOverlay) - lyr2._fadeIn(opts.fadeIn, cb1); - if (msg) - lyr3._fadeIn(opts.fadeIn, cb2); - } - else { - if (opts.showOverlay) - lyr2.show(); - if (msg) - lyr3.show(); - if (opts.onBlock) - opts.onBlock(); - } - - // bind key and mouse events - bind(1, el, opts); - - if (full) { - pageBlock = lyr3[0]; - pageBlockEls = $(opts.focusableElements,pageBlock); - if (opts.focusInput) - setTimeout(focus, 20); - } - else - center(lyr3[0], opts.centerX, opts.centerY); - - if (opts.timeout) { - // auto-unblock - var to = setTimeout(function() { - if (full) - $.unblockUI(opts); - else - $(el).unblock(opts); - }, opts.timeout); - $(el).data('blockUI.timeout', to); - } - } - - // remove the block - function remove(el, opts) { - var count; - var full = (el == window); - var $el = $(el); - var data = $el.data('blockUI.history'); - var to = $el.data('blockUI.timeout'); - if (to) { - clearTimeout(to); - $el.removeData('blockUI.timeout'); - } - opts = $.extend({}, $.blockUI.defaults, opts || {}); - bind(0, el, opts); // unbind events - - if (opts.onUnblock === null) { - opts.onUnblock = $el.data('blockUI.onUnblock'); - $el.removeData('blockUI.onUnblock'); - } - - var els; - if (full) // crazy selector to handle odd field errors in ie6/7 - els = $('body').children().filter('.blockUI').add('body > .blockUI'); - else - els = $el.find('>.blockUI'); - - // fix cursor issue - if ( opts.cursorReset ) { - if ( els.length > 1 ) - els[1].style.cursor = opts.cursorReset; - if ( els.length > 2 ) - els[2].style.cursor = opts.cursorReset; - } - - if (full) - pageBlock = pageBlockEls = null; - - if (opts.fadeOut) { - count = els.length; - els.fadeOut(opts.fadeOut, function() { - if ( --count === 0) - reset(els,data,opts,el); - }); - } - else - reset(els, data, opts, el); - } - - // move blocking element back into the DOM where it started - function reset(els,data,opts,el) { - var $el = $(el); - els.each(function(i,o) { - // remove via DOM calls so we don't lose event handlers - if (this.parentNode) - this.parentNode.removeChild(this); - }); - - if (data && data.el) { - data.el.style.display = data.display; - data.el.style.position = data.position; - if (data.parent) - data.parent.appendChild(data.el); - $el.removeData('blockUI.history'); - } - - if ($el.data('blockUI.static')) { - $el.css('position', 'static'); // #22 - } - - if (typeof opts.onUnblock == 'function') - opts.onUnblock(el,opts); - - // fix issue in Safari 6 where block artifacts remain until reflow - var body = $(document.body), w = body.width(), cssW = body[0].style.width; - body.width(w-1).width(w); - body[0].style.width = cssW; - } - - // bind/unbind the handler - function bind(b, el, opts) { - var full = el == window, $el = $(el); - - // don't bother unbinding if there is nothing to unbind - if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) - return; - - $el.data('blockUI.isBlocked', b); - - // don't bind events when overlay is not in use or if bindEvents is false - if (!full || !opts.bindEvents || (b && !opts.showOverlay)) - return; - - // bind anchors and inputs for mouse and key events - var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; - if (b) - $(document).bind(events, opts, handler); - else - $(document).unbind(events, handler); - - // former impl... - // var $e = $('a,:input'); - // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); - } - - // event handler to suppress keyboard/mouse events when blocking - function handler(e) { - // allow tab navigation (conditionally) - if (e.keyCode && e.keyCode == 9) { - if (pageBlock && e.data.constrainTabKey) { - var els = pageBlockEls; - var fwd = !e.shiftKey && e.target === els[els.length-1]; - var back = e.shiftKey && e.target === els[0]; - if (fwd || back) { - setTimeout(function(){focus(back);},10); - return false; - } - } - } - var opts = e.data; - var target = $(e.target); - if (target.hasClass('blockOverlay') && opts.onOverlayClick) - opts.onOverlayClick(); - - // allow events within the message content - if (target.parents('div.' + opts.blockMsgClass).length > 0) - return true; - - // allow events for content that is not being blocked - return target.parents().children().filter('div.blockUI').length === 0; - } - - function focus(back) { - if (!pageBlockEls) - return; - var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; - if (e) - e.focus(); - } - - function center(el, x, y) { - var p = el.parentNode, s = el.style; - var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); - var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); - if (x) s.left = l > 0 ? (l+'px') : '0'; - if (y) s.top = t > 0 ? (t+'px') : '0'; - } - - function sz(el, p) { - return parseInt($.css(el,p),10)||0; - } - - } - - - /*global define:true */ - if (typeof define === 'function' && define.amd && define.amd.jQuery) { - define(['jquery'], setup); - } else { - setup(jQuery); - } - -})(); diff --git a/vendor/assets/javascripts/jquery.cookie.js b/vendor/assets/javascripts/jquery.cookie.js deleted file mode 100644 index 6a3e394b403d5084b70b8ed7ccdc0d566f2fcbdb..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/jquery.cookie.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * jQuery Cookie plugin - * - * Copyright (c) 2010 Klaus Hartl (stilbuero.de) - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - */ -jQuery.cookie = function (key, value, options) { - - // key and at least value given, set cookie... - if (arguments.length > 1 && String(value) !== "[object Object]") { - options = jQuery.extend({}, options); - - if (value === null || value === undefined) { - options.expires = -1; - } - - if (typeof options.expires === 'number') { - var days = options.expires, t = options.expires = new Date(); - t.setDate(t.getDate() + days); - } - - value = String(value); - - return (document.cookie = [ - encodeURIComponent(key), '=', - options.raw ? value : encodeURIComponent(value), - options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); - } - - // key and possibly options given, get cookie... - options = value || {}; - var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; - return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; -}; diff --git a/vendor/assets/javascripts/jquery.endless-scroll.js b/vendor/assets/javascripts/jquery.endless-scroll.js deleted file mode 100644 index 38db6b0510127ebd9d6dc02e19a75fff0a6af2d8..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/jquery.endless-scroll.js +++ /dev/null @@ -1,128 +0,0 @@ -/** - * Endless Scroll plugin for jQuery - * - * v1.4.8 - * - * Copyright (c) 2008 Fred Wu - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - */ - -/** - * Usage: - * - * // using default options - * $(document).endlessScroll(); - * - * // using some custom options - * $(document).endlessScroll({ - * fireOnce: false, - * fireDelay: false, - * loader: "
    ", - * callback: function(){ - * alert("test"); - * } - * }); - * - * Configuration options: - * - * bottomPixels integer the number of pixels from the bottom of the page that triggers the event - * fireOnce boolean only fire once until the execution of the current event is completed - * fireDelay integer delay the subsequent firing, in milliseconds, 0 or false to disable delay - * loader string the HTML to be displayed during loading - * data string|function plain HTML data, can be either a string or a function that returns a string, - * when passed as a function it accepts one argument: fire sequence (the number - * of times the event triggered during the current page session) - * insertAfter string jQuery selector syntax: where to put the loader as well as the plain HTML data - * callback function callback function, accepts one argument: fire sequence (the number of times - * the event triggered during the current page session) - * resetCounter function resets the fire sequence counter if the function returns true, this function - * could also perform hook actions since it is applied at the start of the event - * ceaseFire function stops the event (no more endless scrolling) if the function returns true - * - * Usage tips: - * - * The plugin is more useful when used with the callback function, which can then make AJAX calls to retrieve content. - * The fire sequence argument (for the callback function) is useful for 'pagination'-like features. - */ - -(function($){ - - $.fn.endlessScroll = function(options) { - - var defaults = { - bottomPixels : 50, - fireOnce : true, - fireDelay : 150, - loader : "
    Loading...
    ", - data : "", - insertAfter : "div:last", - resetCounter : function() { return false; }, - callback : function() { return true; }, - ceaseFire : function() { return false; } - }; - - var options = $.extend({}, defaults, options), - firing = true, - fired = false, - fireSequence = 0, - is_scrollable; - - if (options.ceaseFire.apply(this) === true) - firing = false; - - if (firing === true) { - $(this).scroll(function() { - if (options.ceaseFire.apply(this) === true) { - firing = false; - return; // Scroll will still get called, but nothing will happen - } - - if (this == document || this == window) { - is_scrollable = $(document).height() - $(window).height() <= $(window).scrollTop() + options.bottomPixels; - } else { - // calculates the actual height of the scrolling container - var inner_wrap = $(".endless_scroll_inner_wrap", this); - if (inner_wrap.length == 0) - inner_wrap = $(this).wrapInner("
    ").find(".endless_scroll_inner_wrap"); - is_scrollable = inner_wrap.length > 0 && - (inner_wrap.height() - $(this).height() <= $(this).scrollTop() + options.bottomPixels); - } - - if (is_scrollable && (options.fireOnce == false || (options.fireOnce == true && fired != true))) { - if (options.resetCounter.apply(this) === true) fireSequence = 0; - - fired = true; - fireSequence++; - - $(options.insertAfter).after("
    " + options.loader + "
    "); - - data = typeof options.data == 'function' ? options.data.apply(this, [fireSequence]) : options.data; - - if (data !== false) { - $(options.insertAfter).after("
    " + data + "
    "); - $("#endless_scroll_data").hide().fadeIn(250, function() {$(this).removeAttr("id");}); - - options.callback.apply(this, [fireSequence]); - - if (options.fireDelay !== false || options.fireDelay !== 0) { - $("body").after("
    "); - // slight delay for preventing event firing twice - $("#endless_scroll_marker").fadeTo(options.fireDelay, 1, function() { - $(this).remove(); - fired = false; - }); - } - else - fired = false; - } - - $("#endless_scroll_loader").remove(); - } - }); - } - }; - -})(jQuery); \ No newline at end of file diff --git a/vendor/assets/javascripts/jquery.highlight.js b/vendor/assets/javascripts/jquery.highlight.js deleted file mode 100644 index 7a67cf99844921c9d93757a4da93ce7d84fe4664..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/jquery.highlight.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - -highlight v3 - -Highlights arbitrary terms. - - - -MIT license. - -Johann Burkard - - - -*/ - -jQuery.fn.highlight = function(pat) { - function innerHighlight(node, pat) { - var skip = 0; - if (node.nodeType == 3) { - var pos = node.data.toUpperCase().indexOf(pat); - if (pos >= 0) { - var spannode = document.createElement('span'); - spannode.className = 'highlight_word'; - var middlebit = node.splitText(pos); - var endbit = middlebit.splitText(pat.length); - var middleclone = middlebit.cloneNode(true); - spannode.appendChild(middleclone); - middlebit.parentNode.replaceChild(spannode, middlebit); - skip = 1; - } - } - else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { - for (var i = 0; i < node.childNodes.length; ++i) { - i += innerHighlight(node.childNodes[i], pat); - } - } - return skip; - } - return this.each(function() { - innerHighlight(this, pat.toUpperCase()); - }); -}; - -jQuery.fn.removeHighlight = function() { - return this.find("span.highlight").each(function() { - this.parentNode.firstChild.nodeName; - with (this.parentNode) { - replaceChild(this.firstChild, this); - normalize(); - } - }).end(); -}; diff --git a/vendor/assets/javascripts/jquery.history.js b/vendor/assets/javascripts/jquery.history.js deleted file mode 100644 index 8d4edcd210e2c3b6883084e3afe7c4d7af3d4a6a..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/jquery.history.js +++ /dev/null @@ -1 +0,0 @@ -window.JSON||(window.JSON={}),function(){function f(a){return a<10?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c")&&c[0]);return a>4?a:!1}();return a},m.isInternetExplorer=function(){var a=m.isInternetExplorer.cached=typeof m.isInternetExplorer.cached!="undefined"?m.isInternetExplorer.cached:Boolean(m.getInternetExplorerMajorVersion());return a},m.emulated={pushState:!Boolean(a.history&&a.history.pushState&&a.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)),hashChange:Boolean(!("onhashchange"in a||"onhashchange"in d)||m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8)},m.enabled=!m.emulated.pushState,m.bugs={setHash:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),safariPoll:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),ieDoubleCheck:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<7)},m.isEmptyObject=function(a){for(var b in a)return!1;return!0},m.cloneObject=function(a){var b,c;return a?(b=k.stringify(a),c=k.parse(b)):c={},c},m.getRootUrl=function(){var a=d.location.protocol+"//"+(d.location.hostname||d.location.host);if(d.location.port||!1)a+=":"+d.location.port;return a+="/",a},m.getBaseHref=function(){var a=d.getElementsByTagName("base"),b=null,c="";return a.length===1&&(b=a[0],c=b.href.replace(/[^\/]+$/,"")),c=c.replace(/\/+$/,""),c&&(c+="/"),c},m.getBaseUrl=function(){var a=m.getBaseHref()||m.getBasePageUrl()||m.getRootUrl();return a},m.getPageUrl=function(){var a=m.getState(!1,!1),b=(a||{}).url||d.location.href,c;return c=b.replace(/\/+$/,"").replace(/[^\/]+$/,function(a,b,c){return/\./.test(a)?a:a+"/"}),c},m.getBasePageUrl=function(){var a=d.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,function(a,b,c){return/[^\/]$/.test(a)?"":a}).replace(/\/+$/,"")+"/";return a},m.getFullUrl=function(a,b){var c=a,d=a.substring(0,1);return b=typeof b=="undefined"?!0:b,/[a-z]+\:\/\//.test(a)||(d==="/"?c=m.getRootUrl()+a.replace(/^\/+/,""):d==="#"?c=m.getPageUrl().replace(/#.*/,"")+a:d==="?"?c=m.getPageUrl().replace(/[\?#].*/,"")+a:b?c=m.getBaseUrl()+a.replace(/^(\.\/)+/,""):c=m.getBasePageUrl()+a.replace(/^(\.\/)+/,"")),c.replace(/\#$/,"")},m.getShortUrl=function(a){var b=a,c=m.getBaseUrl(),d=m.getRootUrl();return m.emulated.pushState&&(b=b.replace(c,"")),b=b.replace(d,"/"),m.isTraditionalAnchor(b)&&(b="./"+b),b=b.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),b},m.store={},m.idToState=m.idToState||{},m.stateToId=m.stateToId||{},m.urlToId=m.urlToId||{},m.storedStates=m.storedStates||[],m.savedStates=m.savedStates||[],m.normalizeStore=function(){m.store.idToState=m.store.idToState||{},m.store.urlToId=m.store.urlToId||{},m.store.stateToId=m.store.stateToId||{}},m.getState=function(a,b){typeof a=="undefined"&&(a=!0),typeof b=="undefined"&&(b=!0);var c=m.getLastSavedState();return!c&&b&&(c=m.createStateObject()),a&&(c=m.cloneObject(c),c.url=c.cleanUrl||c.url),c},m.getIdByState=function(a){var b=m.extractId(a.url),c;if(!b){c=m.getStateString(a);if(typeof m.stateToId[c]!="undefined")b=m.stateToId[c];else if(typeof m.store.stateToId[c]!="undefined")b=m.store.stateToId[c];else{for(;;){b=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof m.idToState[b]=="undefined"&&typeof m.store.idToState[b]=="undefined")break}m.stateToId[c]=b,m.idToState[b]=a}}return b},m.normalizeState=function(a){var b,c;if(!a||typeof a!="object")a={};if(typeof a.normalized!="undefined")return a;if(!a.data||typeof a.data!="object")a.data={};b={},b.normalized=!0,b.title=a.title||"",b.url=m.getFullUrl(m.unescapeString(a.url||d.location.href)),b.hash=m.getShortUrl(b.url),b.data=m.cloneObject(a.data),b.id=m.getIdByState(b),b.cleanUrl=b.url.replace(/\??\&_suid.*/,""),b.url=b.cleanUrl,c=!m.isEmptyObject(b.data);if(b.title||c)b.hash=m.getShortUrl(b.url).replace(/\??\&_suid.*/,""),/\?/.test(b.hash)||(b.hash+="?"),b.hash+="&_suid="+b.id;return b.hashedUrl=m.getFullUrl(b.hash),(m.emulated.pushState||m.bugs.safariPoll)&&m.hasUrlDuplicate(b)&&(b.url=b.hashedUrl),b},m.createStateObject=function(a,b,c){var d={data:a,title:b,url:c};return d=m.normalizeState(d),d},m.getStateById=function(a){a=String(a);var c=m.idToState[a]||m.store.idToState[a]||b;return c},m.getStateString=function(a){var b,c,d;return b=m.normalizeState(a),c={data:b.data,title:a.title,url:a.url},d=k.stringify(c),d},m.getStateId=function(a){var b,c;return b=m.normalizeState(a),c=b.id,c},m.getHashByState=function(a){var b,c;return b=m.normalizeState(a),c=b.hash,c},m.extractId=function(a){var b,c,d;return c=/(.*)\&_suid=([0-9]+)$/.exec(a),d=c?c[1]||a:a,b=c?String(c[2]||""):"",b||!1},m.isTraditionalAnchor=function(a){var b=!/[\/\?\.]/.test(a);return b},m.extractState=function(a,b){var c=null,d,e;return b=b||!1,d=m.extractId(a),d&&(c=m.getStateById(d)),c||(e=m.getFullUrl(a),d=m.getIdByUrl(e)||!1,d&&(c=m.getStateById(d)),!c&&b&&!m.isTraditionalAnchor(a)&&(c=m.createStateObject(null,null,e))),c},m.getIdByUrl=function(a){var c=m.urlToId[a]||m.store.urlToId[a]||b;return c},m.getLastSavedState=function(){return m.savedStates[m.savedStates.length-1]||b},m.getLastStoredState=function(){return m.storedStates[m.storedStates.length-1]||b},m.hasUrlDuplicate=function(a){var b=!1,c;return c=m.extractState(a.url),b=c&&c.id!==a.id,b},m.storeState=function(a){return m.urlToId[a.url]=a.id,m.storedStates.push(m.cloneObject(a)),a},m.isLastSavedState=function(a){var b=!1,c,d,e;return m.savedStates.length&&(c=a.id,d=m.getLastSavedState(),e=d.id,b=c===e),b},m.saveState=function(a){return m.isLastSavedState(a)?!1:(m.savedStates.push(m.cloneObject(a)),!0)},m.getStateByIndex=function(a){var b=null;return typeof a=="undefined"?b=m.savedStates[m.savedStates.length-1]:a<0?b=m.savedStates[m.savedStates.length+a]:b=m.savedStates[a],b},m.getHash=function(){var a=m.unescapeHash(d.location.hash);return a},m.unescapeString=function(b){var c=b,d;for(;;){d=a.unescape(c);if(d===c)break;c=d}return c},m.unescapeHash=function(a){var b=m.normalizeHash(a);return b=m.unescapeString(b),b},m.normalizeHash=function(a){var b=a.replace(/[^#]*#/,"").replace(/#.*/,"");return b},m.setHash=function(a,b){var c,e,f;return b!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.setHash,args:arguments,queue:b}),!1):(c=m.escapeHash(a),m.busy(!0),e=m.extractState(a,!0),e&&!m.emulated.pushState?m.pushState(e.data,e.title,e.url,!1):d.location.hash!==c&&(m.bugs.setHash?(f=m.getPageUrl(),m.pushState(null,null,f+"#"+c,!1)):d.location.hash=c),m)},m.escapeHash=function(b){var c=m.normalizeHash(b);return c=a.escape(c),m.bugs.hashEscape||(c=c.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),c},m.getHashByUrl=function(a){var b=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return b=m.unescapeHash(b),b},m.setTitle=function(a){var b=a.title,c;b||(c=m.getStateByIndex(0),c&&c.url===a.url&&(b=c.title||m.options.initialTitle));try{d.getElementsByTagName("title")[0].innerHTML=b.replace("<","<").replace(">",">").replace(" & "," & ")}catch(e){}return d.title=b,m},m.queues=[],m.busy=function(a){typeof a!="undefined"?m.busy.flag=a:typeof m.busy.flag=="undefined"&&(m.busy.flag=!1);if(!m.busy.flag){h(m.busy.timeout);var b=function(){var a,c,d;if(m.busy.flag)return;for(a=m.queues.length-1;a>=0;--a){c=m.queues[a];if(c.length===0)continue;d=c.shift(),m.fireQueueItem(d),m.busy.timeout=g(b,m.options.busyDelay)}};m.busy.timeout=g(b,m.options.busyDelay)}return m.busy.flag},m.busy.flag=!1,m.fireQueueItem=function(a){return a.callback.apply(a.scope||m,a.args||[])},m.pushQueue=function(a){return m.queues[a.queue||0]=m.queues[a.queue||0]||[],m.queues[a.queue||0].push(a),m},m.queue=function(a,b){return typeof a=="function"&&(a={callback:a}),typeof b!="undefined"&&(a.queue=b),m.busy()?m.pushQueue(a):m.fireQueueItem(a),m},m.clearQueue=function(){return m.busy.flag=!1,m.queues=[],m},m.stateChanged=!1,m.doubleChecker=!1,m.doubleCheckComplete=function(){return m.stateChanged=!0,m.doubleCheckClear(),m},m.doubleCheckClear=function(){return m.doubleChecker&&(h(m.doubleChecker),m.doubleChecker=!1),m},m.doubleCheck=function(a){return m.stateChanged=!1,m.doubleCheckClear(),m.bugs.ieDoubleCheck&&(m.doubleChecker=g(function(){return m.doubleCheckClear(),m.stateChanged||a(),!0},m.options.doubleCheckInterval)),m},m.safariStatePoll=function(){var b=m.extractState(d.location.href),c;if(!m.isLastSavedState(b))c=b;else return;return c||(c=m.createStateObject()),m.Adapter.trigger(a,"popstate"),m},m.back=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.back,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.back(!1)}),n.go(-1),!0)},m.forward=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.forward,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.forward(!1)}),n.go(1),!0)},m.go=function(a,b){var c;if(a>0)for(c=1;c<=a;++c)m.forward(b);else{if(!(a<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(c=-1;c>=a;--c)m.back(b)}return m};if(m.emulated.pushState){var o=function(){};m.pushState=m.pushState||o,m.replaceState=m.replaceState||o}else m.onPopState=function(b,c){var e=!1,f=!1,g,h;return m.doubleCheckComplete(),g=m.getHash(),g?(h=m.extractState(g||d.location.href,!0),h?m.replaceState(h.data,h.title,h.url,!1):(m.Adapter.trigger(a,"anchorchange"),m.busy(!1)),m.expectedStateId=!1,!1):(e=m.Adapter.extractEventData("state",b,c)||!1,e?f=m.getStateById(e):m.expectedStateId?f=m.getStateById(m.expectedStateId):f=m.extractState(d.location.href),f||(f=m.createStateObject(null,null,d.location.href)),m.expectedStateId=!1,m.isLastSavedState(f)?(m.busy(!1),!1):(m.storeState(f),m.saveState(f),m.setTitle(f),m.Adapter.trigger(a,"statechange"),m.busy(!1),!0))},m.Adapter.bind(a,"popstate",m.onPopState),m.pushState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.pushState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.pushState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0},m.replaceState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.replaceState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.replaceState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0};if(f){try{m.store=k.parse(f.getItem("History.store"))||{}}catch(p){m.store={}}m.normalizeStore()}else m.store={},m.normalizeStore();m.Adapter.bind(a,"beforeunload",m.clearAllIntervals),m.Adapter.bind(a,"unload",m.clearAllIntervals),m.saveState(m.storeState(m.extractState(d.location.href,!0))),f&&(m.onUnload=function(){var a,b;try{a=k.parse(f.getItem("History.store"))||{}}catch(c){a={}}a.idToState=a.idToState||{},a.urlToId=a.urlToId||{},a.stateToId=a.stateToId||{};for(b in m.idToState){if(!m.idToState.hasOwnProperty(b))continue;a.idToState[b]=m.idToState[b]}for(b in m.urlToId){if(!m.urlToId.hasOwnProperty(b))continue;a.urlToId[b]=m.urlToId[b]}for(b in m.stateToId){if(!m.stateToId.hasOwnProperty(b))continue;a.stateToId[b]=m.stateToId[b]}m.store=a,m.normalizeStore(),f.setItem("History.store",k.stringify(a))},m.intervalList.push(i(m.onUnload,m.options.storeInterval)),m.Adapter.bind(a,"beforeunload",m.onUnload),m.Adapter.bind(a,"unload",m.onUnload));if(!m.emulated.pushState){m.bugs.safariPoll&&m.intervalList.push(i(m.safariStatePoll,m.options.safariPollInterval));if(e.vendor==="Apple Computer, Inc."||(e.appCodeName||"")==="Mozilla")m.Adapter.bind(a,"hashchange",function(){m.Adapter.trigger(a,"popstate")}),m.getHash()&&m.Adapter.onDomLoad(function(){m.Adapter.trigger(a,"hashchange")})}},m.init()}(window) \ No newline at end of file diff --git a/vendor/assets/javascripts/jquery.sticky-kit.min.js b/vendor/assets/javascripts/jquery.sticky-kit.min.js deleted file mode 100644 index e8bb207c5a5f096bafa3a694f88ae1ca1da6a839..0000000000000000000000000000000000000000 --- a/vendor/assets/javascripts/jquery.sticky-kit.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - Sticky-kit v1.1.1 | WTFPL | Leaf Corcoran 2014 | http://leafo.net -*/ -(function(){var k,e;k=this.jQuery||window.jQuery;e=k(window);k.fn.stick_in_parent=function(d){var v,y,n,p,h,C,s,G,q,H;null==d&&(d={});s=d.sticky_class;y=d.inner_scrolling;C=d.recalc_every;h=d.parent;p=d.offset_top;n=d.spacer;v=d.bottoming;null==p&&(p=0);null==h&&(h=void 0);null==y&&(y=!0);null==s&&(s="is_stuck");null==v&&(v=!0);G=function(a,d,q,z,D,t,r,E){var u,F,m,A,c,f,B,w,x,g,b;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);f=a.parent();null!=h&&(f=f.closest(h));if(!f.length)throw"failed to find stick parent"; -u=m=!1;(g=null!=n?n&&a.closest(n):k("
    "))&&g.css("position",a.css("position"));B=function(){var c,e,l;if(!E&&(c=parseInt(f.css("border-top-width"),10),e=parseInt(f.css("padding-top"),10),d=parseInt(f.css("padding-bottom"),10),q=f.offset().top+c+e,z=f.height(),m&&(u=m=!1,null==n&&(a.insertAfter(g),g.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(s),l=!0),D=a.offset().top-parseInt(a.css("margin-top"),10)-p,t=a.outerHeight(!0),r=a.css("float"),g&&g.css({width:a.outerWidth(!0), -height:t,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),l))return b()};B();if(t!==z)return A=void 0,c=p,x=C,b=function(){var b,k,l,h;if(!E&&(null!=x&&(--x,0>=x&&(x=C,B())),l=e.scrollTop(),null!=A&&(k=l-A),A=l,m?(v&&(h=l+t+c>z+q,u&&!h&&(u=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),lb&&!u&&(c-=k,c=Math.max(b-t,c),c=Math.min(p,c),m&&a.css({top:c+"px"})))):l>D&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(s),null==n&&(a.after(g),"left"!==r&&"right"!==r||g.append(a)),a.trigger("sticky_kit:stick")),m&&v&&(null==h&&(h=l+t+c>z+q),!u&&h)))return u=!0,"static"===f.css("position")&&f.css({position:"relative"}),a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")}, -w=function(){B();return b()},F=function(){E=!0;e.off("touchmove",b);e.off("scroll",b);e.off("resize",w);k(document.body).off("sticky_kit:recalc",w);a.off("sticky_kit:detach",F);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});f.position("position","");if(m)return null==n&&("left"!==r&&"right"!==r||a.insertAfter(g),g.remove()),a.removeClass(s)},e.on("touchmove",b),e.on("scroll",b),e.on("resize",w),k(document.body).on("sticky_kit:recalc",w),a.on("sticky_kit:detach",F),setTimeout(b, -0)}};q=0;for(H=this.length;q