Skip to content

Commit

Permalink
Merge pull request #7 from evozon/develop
Browse files Browse the repository at this point in the history
Merge develop into master
  • Loading branch information
ovidiuenache authored Jan 4, 2023
2 parents 959f954 + 30fda6f commit 5bf0752
Show file tree
Hide file tree
Showing 15 changed files with 344 additions and 136 deletions.
Binary file modified bin/future
Binary file not shown.
83 changes: 83 additions & 0 deletions ci/github/future-proofing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Future Proofing
on: push
jobs:
future-proofing:
name: Future Proofing
runs-on: ubuntu-latest #replace this with the platform you target for the upgrade
#services: define the services required to run your test suite
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2 #replace this with the version you target for the upgrade
tools: composer:v2

#run any scripts and installation steps required for executing your project's test suite

- name: Install dependencies
run: composer install --no-interaction --no-scripts --prefer-dist
#env: define the variables required to install your project's dependencies

- name: Bump PHP
run: vendor/bin/future bump-php

- name: Bump dependencies
run: vendor/bin/future bump-deps

- name: Update dependencies
run: composer update -W --no-interaction --no-scripts

- name: Update codebase
run: |
vendor/bin/rector init
vendor/bin/future add-ruleset \\Rector\\Set\\ValueObject\\SetList::CODE_QUALITY
vendor/bin/future add-ruleset \\Rector\\Set\\ValueObject\\SetList::CODING_STYLE
vendor/bin/future add-ruleset \\Rector\\Set\\ValueObject\\SetList::DEAD_CODE
vendor/bin/future add-ruleset \\Rector\\Set\\ValueObject\\SetList::EARLY_RETURN
vendor/bin/future add-ruleset \\Rector\\Set\\ValueObject\\SetList::PSR_4
vendor/bin/future add-ruleset \\Rector\\Set\\ValueObject\\SetList::PRIVATIZATION
vendor/bin/future add-ruleset \\Rector\\Set\\ValueObject\\SetList::TYPE_DECLARATION
vendor/bin/future add-ruleset \\Rector\\Set\\ValueObject\\LevelSetList::UP_TO_PHP_82
vendor/bin/future add-rule \\Rector\\DependencyInjection\\Rector\\Class_\\ActionInjectionToConstructorInjectionRector::class
vendor/bin/future add-rule \\Rector\\RemovingStatic\\Rector\\ClassMethod\\LocallyCalledStaticMethodToNonStaticRector::class
vendor/bin/future add-rule \\Rector\\Restoration\\Rector\\Property\\MakeTypedPropertyNullableIfCheckedRector::class
vendor/bin/future add-rule \\Rector\\Restoration\\Rector\\Class_\\RemoveFinalFromEntityRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ArrowFunction\\AddArrowFunctionReturnTypeRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\Closure\\AddClosureReturnTypeRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddMethodCallBasedStrictParamTypeRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddReturnTypeDeclarationBasedOnParentClassMethodRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddVoidReturnTypeWhereNoReturnRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\ParamTypeByMethodCallTypeRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\ParamTypeByParentCallTypeRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\Param\\ParamTypeFromStrictTypedPropertyRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromReturnNewRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictBoolReturnExprRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNativeCallRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNewArrayRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedPropertyRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\Property\\TypedPropertyFromAssignsRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\Property\\TypedPropertyFromStrictConstructorRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\Property\\TypedPropertyFromStrictGetterMethodReturnTypeRector::class
vendor/bin/future add-rule \\Rector\\TypeDeclaration\\Rector\\Property\\TypedPropertyFromStrictSetUpRector::class
vendor/bin/future add-rule \\Rector\\Visibility\\Rector\\ClassMethod\\ExplicitPublicClassMethodRector::class
vendor/bin/future skip \\Rector\\Php80\\Rector\\Class_\\ClassPropertyAssignToConstructorPromotionRector::class
vendor/bin/future skip \\Rector\\Privatization\\Rector\\Class_\\FinalizeClassesWithoutChildrenRector::class
vendor/bin/future skip \\Rector\\CodingStyle\\Rector\\ClassConst\\VarConstantCommentRector::class
vendor/bin/future skip \\Rector\\DeadCode\\Rector\\ClassMethod\\RemoveUnusedPrivateMethodRector::class
vendor/bin/future skip \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddArrayParamDocTypeRector::class
vendor/bin/future skip \\Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddArrayReturnDocTypeRector::class
vendor/bin/future skip \\Rector\\DeadCode\\Rector\\MethodCall\\RemoveEmptyMethodCallRector::class
vendor/bin/future skip \\Rector\\CodingStyle\\Rector\\String_\\SymplifyQuoteEscapeRector::class
vendor/bin/future skip \\Rector\\CodingStyle\\Rector\\Catch_\\CatchExceptionNameMatchingTypeRector::class
vendor/bin/rector process src --no-progress-bar --no-diffs
#run your project's test suite
#- name: Execute PHPUnit tests
# run: SYMFONY_DEPRECATIONS_HELPER=disabled vendor/bin/phpunit --no-interaction --colors=never
2 changes: 1 addition & 1 deletion future-proofing.yaml → ci/gitlab/future-proofing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ future-proofing:
- curl --silent --show-error "https://getcomposer.org/installer" | php -- --install-dir=/usr/local/bin --filename=composer
- composer install --no-interaction --no-scripts --prefer-dist
script:
- vendor/bin/future bump-php latest
- vendor/bin/future bump-php
- vendor/bin/future bump-deps
- composer update -W --no-interaction --no-scripts
- vendor/bin/rector init
Expand Down
22 changes: 12 additions & 10 deletions add_rule.go → cmd/future/add_rule.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package main
package future

import (
"fmt"
"log"
"strings"

"github.com/spf13/cobra"

"future/internal/rector"
)

var addRule = &cobra.Command{
var AddRule = &cobra.Command{
Use: "add-rule",
Short: "Adds a rector rule",
Long: `Edits the rector.php file to add a new rule`,
Expand All @@ -17,40 +19,40 @@ var addRule = &cobra.Command{
log.Fatalf("Invalid or missing argument! Example: \\\\Rector\\\\Set\\\\ValueObject\\\\LevelSetList::UP_TO_PHP_81::class\n")
}

file, lines, err := loadRectorFile()
file, lines, err := rector.LoadRectorFile()
if err != nil {
log.Fatalf(err.Error())
}
defer file.Close()

ruleInjectionPoint, err := findLineIndexFor(lines, rulesMethod)
ruleInjectionPoint, err := rector.FindLineIndexFor(lines, rector.RulesMethod)
if err != nil {
// if we can't find a ->rules([...]) section, we'll try to find a ->rule(...) section and convert it to a ->rules section
lines = convertSingleRuleToMultipleRules(lines)

ruleInjectionPoint, err = findLineIndexFor(lines, rulesMethod)
ruleInjectionPoint, err = rector.FindLineIndexFor(lines, rector.RulesMethod)
if err != nil {
log.Fatalf(err.Error())
}
}

lines = injectLine(lines, ruleInjectionPoint, args[0])
lines = rector.InjectLine(lines, ruleInjectionPoint, args[0])

if err := writeRectorFile(file, lines); err != nil {
if err := rector.WriteRectorFile(file, lines); err != nil {
log.Fatalf(err.Error())
}
},
}

func convertSingleRuleToMultipleRules(lines []string) []string {
for index, line := range lines {
if !strings.Contains(line, ruleMethod) {
if !strings.Contains(line, rector.RuleMethod) {
continue
}

indentation := line[:strings.Index(line, ruleMethod)]
indentation := line[:strings.Index(line, rector.RuleMethod)]

lines[index] = fmt.Sprintf("%s%s([", indentation, rulesMethod)
lines[index] = fmt.Sprintf("%s%s([", indentation, rector.RulesMethod)
lines = append(
lines[:index+1],
append(
Expand Down
20 changes: 11 additions & 9 deletions add_ruleset.go → cmd/future/add_ruleset.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package main
package future

import (
"log"
"strings"

"github.com/spf13/cobra"

"future/internal/rector"
)

var addRuleset = &cobra.Command{
var AddRuleset = &cobra.Command{
Use: "add-ruleset",
Short: "Adds a rector ruleset",
Long: `Edits the rector.php file to add a new ruleset`,
Expand All @@ -16,7 +18,7 @@ var addRuleset = &cobra.Command{
log.Fatalf("Invalid or missing argument! Example: \\\\Rector\\\\Set\\\\ValueObject\\\\LevelSetList::UP_TO_PHP_81\n")
}

file, lines, err := loadRectorFile()
file, lines, err := rector.LoadRectorFile()
if err != nil {
log.Fatalf(err.Error())
}
Expand All @@ -25,17 +27,17 @@ var addRuleset = &cobra.Command{

setsInjectionPoint, err := findLineIndexForSetsMethod(lines)
if err != nil {
lines = injectSetsMethod(lines, args[0])
if err := writeRectorFile(file, lines); err != nil {
lines = rector.InjectSetsMethod(lines, args[0])
if err := rector.WriteRectorFile(file, lines); err != nil {
log.Fatalf(err.Error())
}

return
}

lines = injectLine(lines, setsInjectionPoint, args[0])
lines = rector.InjectLine(lines, setsInjectionPoint, args[0])

if err := writeRectorFile(file, lines); err != nil {
if err := rector.WriteRectorFile(file, lines); err != nil {
log.Fatalf(err.Error())
}
},
Expand All @@ -61,14 +63,14 @@ func isRulesetArgumentValid(args []string) bool {
}

func findLineIndexForSetsMethod(lines []string) (int, error) {
index, err := findLineIndexFor(lines, setsMethod)
index, err := rector.FindLineIndexFor(lines, rector.SetsMethod)

for err == nil {
if !strings.Contains(lines[index], "//") {
return index, err
}

index, err = findLineIndexFor(lines[index:], setsMethod)
index, err = rector.FindLineIndexFor(lines[index:], rector.SetsMethod)
}

return index, err
Expand Down
16 changes: 9 additions & 7 deletions bump_deps.go → cmd/future/bump_deps.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package main
package future

import (
"encoding/json"
"log"
"os/exec"

"github.com/spf13/cobra"

"future/internal/composer"
)

var bumpDeps = &cobra.Command{
var BumpDeps = &cobra.Command{
Use: "bump-deps",
Short: "Bump composer dependencies",
Long: `Tries to bump all composer dependencies to the latest version`,
Run: func(cmd *cobra.Command, _ []string) {
s, file, err := readComposerJson()
s, file, err := composer.ReadComposerJson()
if err != nil {
log.Fatalf("could not read composer.json: %v\n", err)
}
Expand All @@ -23,19 +25,19 @@ var bumpDeps = &cobra.Command{

updateSchema(deps, &s)

if err := writeComposerJson(file, s); err != nil {
if err := composer.WriteComposerJson(file, s); err != nil {
log.Fatalf("could not write composer.json: %v\n", err)
}
},
}

func updateSchema(deps outdatedDeps, s *schema) {
func updateSchema(deps outdatedDeps, s *composer.Schema) {
// TODO: When trying to bump a dep, do some validation based on the other properties besides Name and Latest
// TODO: We have a lot of info we can use
for _, dep := range deps.Installed {
err := s.setRequireDepVersion(dep.Name, dep.Latest)
err := s.SetRequireDepVersion(dep.Name, dep.Latest)
if err != nil {
err = s.setRequireDevDepVersion(dep.Name, dep.Latest)
err = s.SetRequireDevDepVersion(dep.Name, dep.Latest)
if err != nil {
log.Printf("could not find dep %s in composer.json. tried both require and require-dev", dep.Name)
continue
Expand Down
12 changes: 7 additions & 5 deletions bump_php.go → cmd/future/bump_php.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package future

import (
"fmt"
Expand All @@ -7,13 +7,15 @@ import (
"regexp"

"github.com/spf13/cobra"

"future/internal/composer"
)

const (
defaultPhpVersion = "8.2"
)

var bumpPhp = &cobra.Command{
var BumpPhp = &cobra.Command{
Use: "bump-php",
Short: "Bump PHP version",
Long: `Bump PHP version in composer.json. Must be ran in the root of the project, where the composer.json file is located`,
Expand All @@ -23,15 +25,15 @@ var bumpPhp = &cobra.Command{
phpVersion = defaultPhpVersion
}

s, file, err := readComposerJson()
s, file, err := composer.ReadComposerJson()
if err != nil {
log.Fatalf("could not read composer.json: %v\n", err)
}
defer file.Close()

s.setPhpVersion(phpVersion)
s.SetPhpVersion(phpVersion)

if err := writeComposerJson(file, s); err != nil {
if err := composer.WriteComposerJson(file, s); err != nil {
log.Fatalf("could not write composer.json: %v\n", err)
}
},
Expand Down
23 changes: 23 additions & 0 deletions cmd/future/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package future

import "github.com/spf13/cobra"

func RootCmd() *cobra.Command {
rootCmd := &cobra.Command{
Use: "future",
Short: "Future is a binary that helps upgrade projects",
Long: `To be used in conjunction with the CI future-proofing stage in projects that require upgrading`,
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}

rootCmd.AddCommand(BumpPhp)
rootCmd.AddCommand(BumpDeps)
rootCmd.AddCommand(AddRule)
rootCmd.AddCommand(AddRuleset)
rootCmd.AddCommand(Skip)
rootCmd.AddCommand(RunCmd)

return rootCmd
}
35 changes: 35 additions & 0 deletions cmd/future/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package future

import (
"os"
"os/exec"

"github.com/spf13/cobra"
)

var RunCmd = &cobra.Command{
Use: "run",
Short: "Run any shell command through the future binary",
Long: `Run any shell command through the future binary`,
Example: `bin/future run ls -all`,
DisableFlagParsing: true,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
var shArgs []string

if len(args) > 1 {
shArgs = args[1:]
}

sh := exec.Command(args[0], shArgs...)

cmd.Println(sh.String())

sh.Stdout = cmd.OutOrStdout()
if err := sh.Run(); err != nil {
_ = cmd.Help()
cmd.PrintErrf("Failed to run command: %v\n", err)
os.Exit(1)
}
},
}
Loading

0 comments on commit 5bf0752

Please sign in to comment.