planter-cli 0.0.4 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.gitmodules +3 -0
  4. data/.rubocop.yml +1 -1
  5. data/CHANGELOG.md +31 -0
  6. data/README.md +33 -4
  7. data/Rakefile +52 -16
  8. data/bin/plant +2 -2
  9. data/docker/Dockerfile +2 -4
  10. data/docker/Dockerfile-2.6 +4 -6
  11. data/docker/Dockerfile-2.7 +4 -6
  12. data/docker/Dockerfile-3.0 +4 -5
  13. data/docker/Dockerfile-3.3 +11 -0
  14. data/docker/sources.list +11 -0
  15. data/lib/planter/array.rb +17 -0
  16. data/lib/planter/fileentry.rb +5 -1
  17. data/lib/planter/filelist.rb +13 -4
  18. data/lib/planter/hash.rb +17 -1
  19. data/lib/planter/plant.rb +5 -3
  20. data/lib/planter/prompt.rb +5 -5
  21. data/lib/planter/string.rb +22 -0
  22. data/lib/planter/tag.rb +91 -0
  23. data/lib/planter/version.rb +1 -1
  24. data/lib/planter.rb +34 -18
  25. data/lib/tty-spinner/.editorconfig +9 -0
  26. data/lib/tty-spinner/.github/FUNDING.yml +1 -0
  27. data/lib/tty-spinner/.github/ISSUE_TEMPLATE/BUG_REPORT.md +31 -0
  28. data/lib/tty-spinner/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +23 -0
  29. data/lib/tty-spinner/.github/ISSUE_TEMPLATE/config.yml +5 -0
  30. data/lib/tty-spinner/.github/PULL_REQUEST_TEMPLATE.md +19 -0
  31. data/lib/tty-spinner/.github/workflows/ci.yml +59 -0
  32. data/lib/tty-spinner/.gitignore +14 -0
  33. data/lib/tty-spinner/.rspec +2 -0
  34. data/lib/tty-spinner/.rubocop.yml +78 -0
  35. data/lib/tty-spinner/CHANGELOG.md +151 -0
  36. data/lib/tty-spinner/CODE_OF_CONDUCT.md +132 -0
  37. data/lib/tty-spinner/Gemfile +17 -0
  38. data/lib/tty-spinner/LICENSE.txt +22 -0
  39. data/lib/tty-spinner/README.md +581 -0
  40. data/lib/tty-spinner/Rakefile +10 -0
  41. data/lib/tty-spinner/appveyor.yml +33 -0
  42. data/lib/tty-spinner/bin/console +14 -0
  43. data/lib/tty-spinner/bin/setup +8 -0
  44. data/lib/tty-spinner/demo.gif +0 -0
  45. data/lib/tty-spinner/examples/auto_spin.rb +10 -0
  46. data/lib/tty-spinner/examples/basic.rb +10 -0
  47. data/lib/tty-spinner/examples/clear.rb +11 -0
  48. data/lib/tty-spinner/examples/color.rb +14 -0
  49. data/lib/tty-spinner/examples/error.rb +11 -0
  50. data/lib/tty-spinner/examples/formats.rb +13 -0
  51. data/lib/tty-spinner/examples/hide_cursor.rb +14 -0
  52. data/lib/tty-spinner/examples/log.rb +13 -0
  53. data/lib/tty-spinner/examples/multi/basic.rb +15 -0
  54. data/lib/tty-spinner/examples/multi/basic_top_level.rb +15 -0
  55. data/lib/tty-spinner/examples/multi/custom_style.rb +28 -0
  56. data/lib/tty-spinner/examples/multi/files.rb +16 -0
  57. data/lib/tty-spinner/examples/multi/jobs.rb +11 -0
  58. data/lib/tty-spinner/examples/multi/multi.rb +19 -0
  59. data/lib/tty-spinner/examples/multi/multi_top_level.rb +20 -0
  60. data/lib/tty-spinner/examples/multi/pause.rb +28 -0
  61. data/lib/tty-spinner/examples/multi/threaded.rb +30 -0
  62. data/lib/tty-spinner/examples/pause.rb +24 -0
  63. data/lib/tty-spinner/examples/run.rb +20 -0
  64. data/lib/tty-spinner/examples/success.rb +11 -0
  65. data/lib/tty-spinner/examples/threaded.rb +13 -0
  66. data/lib/tty-spinner/examples/update.rb +13 -0
  67. data/lib/tty-spinner/lib/tty/spinner/formats.rb +274 -0
  68. data/lib/tty-spinner/lib/tty/spinner/multi.rb +352 -0
  69. data/lib/tty-spinner/lib/tty/spinner/version.rb +7 -0
  70. data/lib/tty-spinner/lib/tty/spinner.rb +604 -0
  71. data/lib/tty-spinner/lib/tty-spinner.rb +2 -0
  72. data/lib/tty-spinner/spec/spec_helper.rb +52 -0
  73. data/lib/tty-spinner/spec/unit/auto_spin_spec.rb +25 -0
  74. data/lib/tty-spinner/spec/unit/clear_spec.rb +16 -0
  75. data/lib/tty-spinner/spec/unit/error_spec.rb +53 -0
  76. data/lib/tty-spinner/spec/unit/events_spec.rb +35 -0
  77. data/lib/tty-spinner/spec/unit/formats_spec.rb +9 -0
  78. data/lib/tty-spinner/spec/unit/frames_spec.rb +31 -0
  79. data/lib/tty-spinner/spec/unit/hide_cursor_spec.rb +51 -0
  80. data/lib/tty-spinner/spec/unit/job_spec.rb +12 -0
  81. data/lib/tty-spinner/spec/unit/join_spec.rb +10 -0
  82. data/lib/tty-spinner/spec/unit/log_spec.rb +60 -0
  83. data/lib/tty-spinner/spec/unit/multi/auto_spin_spec.rb +32 -0
  84. data/lib/tty-spinner/spec/unit/multi/error_spec.rb +107 -0
  85. data/lib/tty-spinner/spec/unit/multi/line_inset_spec.rb +57 -0
  86. data/lib/tty-spinner/spec/unit/multi/on_spec.rb +11 -0
  87. data/lib/tty-spinner/spec/unit/multi/register_spec.rb +46 -0
  88. data/lib/tty-spinner/spec/unit/multi/spin_spec.rb +101 -0
  89. data/lib/tty-spinner/spec/unit/multi/stop_spec.rb +95 -0
  90. data/lib/tty-spinner/spec/unit/multi/success_spec.rb +108 -0
  91. data/lib/tty-spinner/spec/unit/new_spec.rb +25 -0
  92. data/lib/tty-spinner/spec/unit/pause_spec.rb +43 -0
  93. data/lib/tty-spinner/spec/unit/reset_spec.rb +19 -0
  94. data/lib/tty-spinner/spec/unit/run_spec.rb +30 -0
  95. data/lib/tty-spinner/spec/unit/spin_spec.rb +117 -0
  96. data/lib/tty-spinner/spec/unit/stop_spec.rb +88 -0
  97. data/lib/tty-spinner/spec/unit/success_spec.rb +53 -0
  98. data/lib/tty-spinner/spec/unit/tty_spec.rb +8 -0
  99. data/lib/tty-spinner/spec/unit/update_spec.rb +85 -0
  100. data/lib/tty-spinner/tasks/console.rake +11 -0
  101. data/lib/tty-spinner/tasks/coverage.rake +11 -0
  102. data/lib/tty-spinner/tasks/spec.rake +29 -0
  103. data/lib/tty-spinner/tty-spinner.gemspec +36 -0
  104. data/planter-cli.gemspec +1 -0
  105. data/scripts/runtests.sh +1 -1
  106. data/spec/cli_spec.rb +27 -0
  107. data/spec/planter/hash_spec.rb +27 -0
  108. data/spec/planter_spec.rb +15 -0
  109. data/spec/spec_helper.rb +26 -0
  110. data/spec/templates/test/%%project:snake%%.rtf +10 -0
  111. data/spec/templates/test/Rakefile +6 -0
  112. data/spec/templates/test/_planter.yml +3 -6
  113. data/spec/templates/test/test.rb +5 -0
  114. data/src/_README.md +20 -3
  115. metadata +108 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5318772de94f6948e72fcf61709d9b0cf42c3518a775e47eaa816e8d432cf0f0
4
- data.tar.gz: fcc04239c8d4c74af78f7da138d862f3a01ee053740cda5ad28e8e1019c11a29
3
+ metadata.gz: a4b54e16d9836121fd1fa5831a1c7433056f45e9372b9985640a6052a2852aab
4
+ data.tar.gz: d2a57bd628c33f9dcccdc605577a11e4aaacbeef3a0c261f96835771f8fc0223
5
5
  SHA512:
6
- metadata.gz: 55fd5cdd6bbede37bd171df3c6686fc4ca14c869895cf122f7a38997b46121516e32342ab7f8625b26762fba668cd73611c0edeac101fdf3d2d6ec325460dbfa
7
- data.tar.gz: 865480b6ed5efda83cba2b0314bf1afd685eed88c2c930e6b705e4fb104da3fadc0afd85211ea2a4930370d0c786df342a6dbf7c4f0ab371b9122f6df895150b
6
+ metadata.gz: 0001cffb09df38704dbeadb6b68b42418a0b02741430fd3932fcdf845d53052945d1e51dd5bd6227c8f02cd70fbbd86f8d037bd1ef2da7547c5ae3f859320a93
7
+ data.tar.gz: b612aa38f0aaa7d1746b8715e032e93550735510b9e0e5f90cbdaef35d0cb0eea3f9afbc8c1f001f03eb40c0de41f7773e5ef7f4799e1792a4543be36ff4074b
data/.gitignore CHANGED
@@ -43,3 +43,6 @@ Gemfile.lock
43
43
  .rvmrc
44
44
  /test
45
45
  .history
46
+ spec/test/
47
+ spec/noop
48
+ bundle
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "lib/planter/tty-spinner"]
2
+ path = lib/planter/tty-spinner
3
+ url = git@github.com:piotrmurach/tty-spinner.git
data/.rubocop.yml CHANGED
@@ -41,7 +41,7 @@ Metrics/BlockLength:
41
41
  Max: 45
42
42
  Exclude:
43
43
  - Rakefile
44
- - bin/howzit
44
+ - bin/untitled
45
45
  - lib/*.rb
46
46
 
47
47
  Metrics/ClassLength:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,34 @@
1
+ ### 3.0.2
2
+
3
+ 2024-09-01 09:46
4
+
5
+ #### IMPROVED
6
+
7
+ - Add basic CLI tests
8
+ - Better debug output and output of info messages above spinner
9
+ - Handle Bash-style globs in file: filenames
10
+
11
+ ### 3.0.1
12
+
13
+ 2024-08-31 14:19
14
+
15
+ ### 3.0.0-alpha
16
+
17
+ 2024-08-31 14:18
18
+
19
+ #### NEW
20
+
21
+ - Initial release
22
+ - Preserve Finder tags when planting (config option `preserve_tags: true`)
23
+
24
+ #### IMPROVED
25
+
26
+ - More tests
27
+
28
+ #### FIXED
29
+
30
+ - Code refactoring
31
+
1
32
  ### 0.0.3
2
33
 
3
34
  2024-08-28 09:46
data/README.md CHANGED
@@ -14,11 +14,22 @@ If [Gum](https://github.com/charmbracelet/gum) is available it will be used for
14
14
 
15
15
  ## Configuration
16
16
 
17
- Planter's base configuration is in `~/.config/planter/config.yml`. This file can contain any of the keys used in templates (see below) and will serve as a base configuration for all templates. Any key defined in this file will be overridden if it exists in a template.
17
+ Planter's base configuration is in `~/.config/planter/planter.yml`. This file can contain any of the keys used in templates (see below) and will serve as a base configuration for all templates. Any key defined in this file will be overridden if it exists in a template.
18
18
 
19
- ### Scripts.
19
+ Example config (written on first run):
20
20
 
21
- Scripts for execution after planting can be stored in `~/.config/planter/scripts` and referenced by filename only. Alternatively, scripts may be stored within a template in a `_scritps` subfolder.
21
+ ```yaml
22
+ files:
23
+ .DS_Store: ignore
24
+ "*.tmp": ignore
25
+ "*.bak": ignore
26
+ git_init: false
27
+ preserve_tags: true
28
+ ```
29
+
30
+ ### Scripts
31
+
32
+ Scripts for execution after planting can be stored in `~/.config/planter/scripts` and referenced by filename only. Alternatively, scripts may be stored within a template in a `_scripts` subfolder.
22
33
 
23
34
  Scripts can be executable files in any language, and receive the template directory and the planted directory as arguments $1 and $2.
24
35
 
@@ -49,6 +60,10 @@ replacements: # Dictionary of pattern/replacments for regex substitution, see [R
49
60
  repo: # If a repository URL is provided, it will be pulled and duplicated instead of copying a file structure
50
61
  ```
51
62
 
63
+ #### Default values in template strings
64
+
65
+ In a template you can add a default value for a placholder by adding `%default value` to it. For example, `%%project%Default Project%%` will set the placeholder to `Default Project` if the variable value matches the default value in the configuration. This allows you to accept the default on the command line but have a different value inserted in the template. To use another variable in its place, use `$KEY` in the placeholder, e.g. `%%project%$title%%` will replace the `project` key with the value of `title` if the default is selected. Modifiers can be used on either side of the `%`, e.g. `%%project%$title:snake%%`.
66
+
52
67
  ### File-specific handling
53
68
 
54
69
  A `files` dictionary can specify how to handle specific files. Options are `copy`, `overwrite`, `merge`, or `ask`. The key for each entry is a filename or glob that matches the source filename (accounting for template variables if applicable):
@@ -59,6 +74,8 @@ files:
59
74
  "%%title%%.md": overwrite
60
75
  ```
61
76
 
77
+ Filenames can include wildcards (`*`, `?`), and Bash-style globbing (`[0-9]`, `[a-z]`, `{one,two,three}`).
78
+
62
79
  If `merge` is specified, then the source file is scanned for merge comments and those are merged if they don't exist in the copied/existing file. If no merge comments are defined, then the entire contents of the source file are appended to the destination file (unless the file already matches the source). Merge comments start with `merge` and end with `/merge` and can have any comment syntax preceding them, for example:
63
80
 
64
81
  ```
@@ -67,6 +84,14 @@ Merged content
67
84
  // /merge
68
85
  ```
69
86
 
87
+ Or
88
+
89
+ ```
90
+ # merge
91
+ Merged content
92
+ # /merge
93
+ ```
94
+
70
95
  By default files that already exist in the destination directory are not overwritten, and merging allows you to add missing parts to a Rakefile or Makefile, for example.
71
96
 
72
97
  If `ask` is specified, a memu will be provided on the command line asking how to handle a file. If the file doesn't already exist, you will be asked only whether to copy the file or not. If it does exist, `overwrite` and `merge` options will be added.
@@ -81,7 +106,11 @@ replacements:
81
106
  "(main|app)\.js": "%%script:lower%%.js"
82
107
  ```
83
108
 
84
- Replacements are performed on both file/directory names and file contents.
109
+ Replacements are performed on both file/directory names and file contents. This is especially handy when the source of the plant is a Git repo, allowing the replacement of elements without having to create %%templated%% filenames and contents.
110
+
111
+ ### Finder Tags
112
+
113
+ If `preserve_tags` is set to `true` in the config (either base or template), then existing Finder tags on the file or folder will be copied to the new file when a template is planted.
85
114
 
86
115
  ## Usage
87
116
 
data/Rakefile CHANGED
@@ -38,17 +38,6 @@ end
38
38
  desc 'Clobber files'
39
39
  task clobber: :clobber_packages
40
40
 
41
- desc 'Development version check'
42
- task :ver do
43
- gver = `git ver`
44
- cver = IO.read(File.join(File.dirname(__FILE__), 'CHANGELOG.md')).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
45
- res = `grep VERSION lib/planter/version.rb`
46
- version = res.match(/VERSION *= *['"](\d+\.\d+\.\d+(\w+)?)/)[1]
47
- puts "git tag: #{gver}"
48
- puts "version.rb: #{version}"
49
- puts "changelog: #{cver}"
50
- end
51
-
52
41
  desc 'Get Script Version'
53
42
  task :sver do
54
43
  res = `grep VERSION lib/planter/version.rb`
@@ -56,11 +45,6 @@ task :sver do
56
45
  print version
57
46
  end
58
47
 
59
- desc 'Changelog version check'
60
- task :cver do
61
- puts IO.read(File.join(File.dirname(__FILE__), 'CHANGELOG.md')).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
62
- end
63
-
64
48
  desc 'Run tests in Docker'
65
49
  task :dockertest, :version, :login, :attempt do |_, args|
66
50
  args.with_defaults(version: 'all', login: false, attempt: 1)
@@ -78,6 +62,9 @@ task :dockertest, :version, :login, :attempt do |_, args|
78
62
  Rake::Task['dockertest'].invoke(v, false)
79
63
  end
80
64
  Process.exit 0
65
+ when /^3\.?3/
66
+ img = 'plantertest33'
67
+ file = 'docker/Dockerfile-3.3'
81
68
  when /^3/
82
69
  version = '3.0'
83
70
  img = 'plantertest3'
@@ -130,3 +117,52 @@ end
130
117
 
131
118
  desc 'alias for build'
132
119
  task package: :build
120
+
121
+ desc 'Development version check'
122
+ task :ver do
123
+ gver = `git ver`
124
+ cver = IO.read(File.join(File.dirname(__FILE__), 'CHANGELOG.md')).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
125
+ res = `grep VERSION lib/untitled/version.rb`
126
+ version = res.match(/VERSION *= *['"](\d+\.\d+\.\d+(\w+)?)/)[1]
127
+ puts "git tag: #{gver}"
128
+ puts "version.rb: #{version}"
129
+ puts "changelog: #{cver}"
130
+ end
131
+
132
+ desc 'Changelog version check'
133
+ task :cver do
134
+ puts IO.read(File.join(File.dirname(__FILE__), 'CHANGELOG.md')).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
135
+ end
136
+
137
+ desc 'Alias for build'
138
+ task package: :build
139
+
140
+ desc 'Bump incremental version number'
141
+ task :bump, :type do |_, args|
142
+ args.with_defaults(type: 'inc')
143
+ version_file = 'lib/untitled/version.rb'
144
+ content = IO.read(version_file)
145
+ content.sub!(/VERSION = '(?<major>\d+)\.(?<minor>\d+)\.(?<inc>\d+)(?<pre>\S+)?'/) do
146
+ m = Regexp.last_match
147
+ major = m['major'].to_i
148
+ minor = m['minor'].to_i
149
+ inc = m['inc'].to_i
150
+ pre = m['pre']
151
+
152
+ case args[:type]
153
+ when /^maj/
154
+ major += 1
155
+ minor = 0
156
+ inc = 0
157
+ when /^min/
158
+ minor += 1
159
+ inc = 0
160
+ else
161
+ inc += 1
162
+ end
163
+
164
+ $stdout.puts "At version #{major}.#{minor}.#{inc}#{pre}"
165
+ "VERSION = '#{major}.#{minor}.#{inc}#{pre}'"
166
+ end
167
+ File.open(version_file, 'w+') { |f| f.puts content }
168
+ end
data/bin/plant CHANGED
@@ -54,7 +54,7 @@ opts.on('-o', '--overwrite', 'Overwrite existing files') do
54
54
  Planter.overwrite = true
55
55
  end
56
56
 
57
- opts.on_tail('--base-dir', 'Use an alternate base directory for config and templates') do |opt|
57
+ opts.on_tail('--base-dir DIRECTORY', 'Use an alternate base directory for config and templates') do |opt|
58
58
  Planter.base_dir = opt
59
59
  end
60
60
 
@@ -105,7 +105,7 @@ elsif ARGV.count.zero?
105
105
  end
106
106
 
107
107
  ARGV.each do |template|
108
- Planter.spinner.update(title: 'Initializing configuration')
108
+ # Planter.spinner.update(title: 'Initializing configuration')
109
109
  Planter.config = template
110
110
  app = Planter::Plant.new
111
111
  app.plant
data/docker/Dockerfile CHANGED
@@ -1,12 +1,10 @@
1
1
  FROM ruby:3.0.1
2
- # RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
3
2
  RUN mkdir /planter
4
3
  WORKDIR /planter
5
-
6
4
  RUN gem install bundler:2.2.29
7
- RUN apt-get update -y
5
+ COPY ./docker/sources.list /etc/apt/sources.list
6
+ RUN apt-get update -y --allow-insecure-repositories || true
8
7
  RUN apt-get install -y less vim
9
8
  COPY ./docker/inputrc /root/.inputrc
10
9
  COPY ./docker/bash_profile /root/.bash_profile
11
- RUN mkdir -p /root/.config/planter/templates/test
12
10
  CMD ["/planter/scripts/runtests.sh"]
@@ -1,12 +1,10 @@
1
1
  FROM ruby:2.6
2
- # RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
3
- RUN mkdir /howzit
4
- WORKDIR /howzit
5
- # COPY ./ /howzit/
2
+ RUN mkdir /planter
3
+ WORKDIR /planter
6
4
  RUN gem install bundler:2.2.29
7
- RUN apt-get update -y
5
+ COPY ./docker/sources.list /etc/apt/sources.list
6
+ RUN apt-get update -y --allow-insecure-repositories || true
8
7
  RUN apt-get install -y less vim
9
8
  COPY ./docker/inputrc /root/.inputrc
10
9
  COPY ./docker/bash_profile /root/.bash_profile
11
- RUN mkdir -p /root/.config/planter/templates/test
12
10
  CMD ["/planter/scripts/runtests.sh"]
@@ -1,12 +1,10 @@
1
1
  FROM ruby:2.7
2
- # RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
3
- RUN mkdir /howzit
4
- WORKDIR /howzit
5
- # COPY ./ /howzit/
2
+ RUN mkdir /planter
3
+ WORKDIR /planter
6
4
  RUN gem install bundler:2.2.29
7
- RUN apt-get update -y
5
+ COPY ./docker/sources.list /etc/apt/sources.list
6
+ RUN apt-get update -y --allow-insecure-repositories || true
8
7
  RUN apt-get install -y less vim
9
8
  COPY ./docker/inputrc /root/.inputrc
10
9
  COPY ./docker/bash_profile /root/.bash_profile
11
- RUN mkdir -p /root/.config/planter/templates/test
12
10
  CMD ["/planter/scripts/runtests.sh"]
@@ -1,10 +1,9 @@
1
1
  FROM ruby:3.0.0
2
- # RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
3
- RUN mkdir /howzit
4
- WORKDIR /howzit
5
- # COPY ./ /howzit/
2
+ RUN mkdir /planter
3
+ WORKDIR /planter
6
4
  RUN gem install bundler:2.2.29
7
- RUN apt-get update -y
5
+ COPY ./docker/sources.list /etc/apt/sources.list
6
+ RUN apt-get update -y --allow-insecure-repositories || true
8
7
  RUN apt-get install -y less vim
9
8
  COPY ./docker/inputrc /root/.inputrc
10
9
  COPY ./docker/bash_profile /root/.bash_profile
@@ -0,0 +1,11 @@
1
+ FROM ruby:3.3.0
2
+ # RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
3
+ RUN mkdir /planter
4
+ WORKDIR /planter
5
+ RUN gem install bundler:2.2.29
6
+ COPY ./docker/sources.list /etc/apt/sources.list
7
+ RUN apt-get update -y --allow-insecure-repositories || true
8
+ RUN apt-get install -y less vim
9
+ COPY ./docker/inputrc /root/.inputrc
10
+ COPY ./docker/bash_profile /root/.bash_profile
11
+ CMD ["/planter/scripts/runtests.sh"]
@@ -0,0 +1,11 @@
1
+ deb http://archive.ubuntu.com/ubuntu/ focal main restricted
2
+ deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted
3
+ deb http://archive.ubuntu.com/ubuntu/ focal universe
4
+ deb http://archive.ubuntu.com/ubuntu/ focal-updates universe
5
+ deb http://archive.ubuntu.com/ubuntu/ focal multiverse
6
+ deb http://archive.ubuntu.com/ubuntu/ focal-updates multiverse
7
+ deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse
8
+
9
+ deb http://security.ubuntu.com/ubuntu focal-security main restricted
10
+ deb http://security.ubuntu.com/ubuntu focal-security universe
11
+ deb http://security.ubuntu.com/ubuntu focal-security multiversesudo apt update
data/lib/planter/array.rb CHANGED
@@ -58,5 +58,22 @@ module Planter
58
58
  end
59
59
  end
60
60
  end
61
+
62
+ #
63
+ # Destructive version of #symbolize_keys
64
+ #
65
+ # @return [Array] Array with symbolized keys
66
+ #
67
+ def symbolize_keys!
68
+ replace deep_dup.symbolize_keys
69
+ end
70
+
71
+ ## Deep duplicate an array of hashes or arrays
72
+ ##
73
+ ## @return [Array] Deep duplicated array
74
+ ##
75
+ def deep_dup
76
+ map { |v| v.is_a?(Hash) || v.is_a?(Array) ? v.deep_dup : v.dup }
77
+ end
61
78
  end
62
79
  end
@@ -7,7 +7,7 @@ module Planter
7
7
  attr_accessor :operation
8
8
 
9
9
  # File path and target path
10
- attr_reader :file, :target
10
+ attr_reader :file, :target, :tags
11
11
 
12
12
  ##
13
13
  ## Initialize a FileEntry object
@@ -19,10 +19,14 @@ module Planter
19
19
  ## @return [FileEntry] a Hash of parameters
20
20
  ##
21
21
  def initialize(file, target, operation)
22
+ return nil unless File.exist?(file)
23
+
22
24
  @file = file
23
25
  @target = target
24
26
  @operation = operation
25
27
 
28
+ @tags = Tag.get(file)
29
+
26
30
  super()
27
31
  end
28
32
 
@@ -39,7 +39,7 @@ module Planter
39
39
  handle_operator(file)
40
40
  end
41
41
  rescue StandardError => e
42
- Planter.notify("#{e}\n#{e.backtrace}", :debug)
42
+ Planter.notify("#{e}\n#{e.backtrace}", :debug, above_spinner: true)
43
43
  Planter.notify('Error copying files/directories', :error, exit_code: 128)
44
44
  end
45
45
 
@@ -61,6 +61,14 @@ module Planter
61
61
  else
62
62
  copy_file(entry)
63
63
  end
64
+
65
+ apply_tags(entry)
66
+ end
67
+
68
+ def apply_tags(entry)
69
+ return unless Planter.config[:preserve_tags]
70
+
71
+ Tag.copy(entry.file, entry.target) if File.exist?(entry.target)
64
72
  end
65
73
 
66
74
  ##
@@ -133,7 +141,8 @@ module Planter
133
141
  # If there are any merge sections left, merge them with the target file
134
142
  if merges.count.positive?
135
143
  File.open(entry.target, 'w') { |f| f.puts "#{target_content.chomp}\n\n#{merges.join("\n\n")}" }
136
- Planter.notify("Merged #{entry.file} => #{entry.target} (#{merges.count} merges)", :debug)
144
+ Planter.notify("[Merged] #{entry.file} => #{entry.target} (#{merges.count} merges)", :debug,
145
+ above_spinner: true)
137
146
  else
138
147
  # If there are no merge sections left, copy the file instead
139
148
  copy_file(entry)
@@ -158,12 +167,12 @@ module Planter
158
167
  # Copy the file if it isn't a directory
159
168
  FileUtils.cp(file.file, file.target) unless File.directory?(file.file)
160
169
  # Log a message to the console
161
- Planter.notify("Copied #{file.file} => #{file.target}", :debug)
170
+ Planter.notify("[Copied] #{file.file} => #{file.target}", :debug, above_spinner: true)
162
171
  # Return true to indicate success
163
172
  true
164
173
  else
165
174
  # Log a message to the console
166
- Planter.notify("Skipped #{file.file} => #{file.target}", :debug)
175
+ Planter.notify("[Skipped] #{file.file} => #{file.target}", :debug, above_spinner: true)
167
176
  # Return false to indicate that the copy was skipped
168
177
  false
169
178
  end
data/lib/planter/hash.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Hash helpers
4
3
  module Planter
5
4
  ## Hash helpers
6
5
  class ::Hash
@@ -18,6 +17,14 @@ module Planter
18
17
  end
19
18
  end
20
19
 
20
+ ## Destructive version of #stringify_keys
21
+ ##
22
+ ## @return [Hash] Hash with stringified keys
23
+ ##
24
+ def stringify_keys!
25
+ replace stringify_keys
26
+ end
27
+
21
28
  ##
22
29
  ## Turn all keys into symbols
23
30
  ##
@@ -33,6 +40,15 @@ module Planter
33
40
  end
34
41
  end
35
42
 
43
+ ##
44
+ ## Destructive version of #symbolize_keys
45
+ ##
46
+ ## @return [Hash] Hash with symbolized keys
47
+ ##
48
+ def symbolize_keys!
49
+ replace symbolize_keys
50
+ end
51
+
36
52
  ##
37
53
  ## Deep merge a hash
38
54
  ##
data/lib/planter/plant.rb CHANGED
@@ -68,6 +68,8 @@ module Planter
68
68
  ## @example Pass a GitHub-style repo path and get full url
69
69
  ## expand_repo("ttscoff/planter-cli") #=> https://github.com/ttscoff/planter-cli.git
70
70
  ##
71
+ ## @param repo [String] The repo
72
+ ##
71
73
  ## @return { description_of_the_return_value }
72
74
  ##
73
75
  def expand_repo(repo)
@@ -185,14 +187,14 @@ module Planter
185
187
  new_content.gsub!(%r{^.{.4}/?merge *.{,4}\n}, '') if new_content =~ /^.{.4}merge *\n/
186
188
 
187
189
  unless content == new_content
188
- Planter.notify("Applying variables to #{file}", :debug)
190
+ Planter.notify("Applying variables to #{file}", :debug, above_spinner: true)
189
191
  File.open(file, 'w') { |f| f.puts new_content }
190
192
  end
191
193
  end
192
194
 
193
195
  true
194
196
  rescue StandardError => e
195
- Planter.notify("#{e}\n#{e.backtrace}", :debug)
197
+ Planter.notify("#{e}\n#{e.backtrace}", :debug, above_spinner: true)
196
198
  'Error updating files/directories'
197
199
  end
198
200
 
@@ -213,7 +215,7 @@ module Planter
213
215
 
214
216
  true
215
217
  rescue StandardError => e
216
- Planter.notify("#{e}\n#{e.backtrace}", :debug)
218
+ Planter.notify("#{e}\n#{e.backtrace}", :debug, above_spinner: true)
217
219
  'Error initializing git'
218
220
  end
219
221
  end
@@ -54,10 +54,10 @@ module Planter
54
54
  else
55
55
  read_line
56
56
  end
57
- Planter.notify("{dw}#{prompt}: {dy}#{res}{x}", :debug)
57
+ Planter.notify("{dw}#{prompt} => {dy}#{res}{x}", :debug, newline: false)
58
58
  res
59
59
  rescue TTY::Reader::InputInterrupt
60
- raise Errors::InputError('Canceled')
60
+ raise Errors::InputError.new('Canceled')
61
61
  end
62
62
 
63
63
  private
@@ -116,7 +116,7 @@ module Planter
116
116
  default = date_default
117
117
 
118
118
  default = default ? " {bw}[#{default}]" : ''
119
- Planter.notify("{by}#{prompt} (natural language)#{default}")
119
+ Planter.notify("{by}#{prompt} (natural language)#{default}", newline: false)
120
120
  line = @gum ? read_line_gum : read_line_tty
121
121
  return default unless line
122
122
 
@@ -135,7 +135,7 @@ module Planter
135
135
  def read_line(prompt: nil)
136
136
  prompt ||= @prompt
137
137
  default = @default ? " {bw}[#{@default}]" : ''
138
- Planter.notify("{by}#{prompt}#{default}")
138
+ Planter.notify("{by}#{prompt}#{default}", newline: false)
139
139
 
140
140
  res = @gum ? read_line_gum : read_line_tty
141
141
 
@@ -156,7 +156,7 @@ module Planter
156
156
  def read_lines(prompt: nil)
157
157
  prompt ||= @prompt
158
158
  save = @gum ? 'Ctrl-J for newline, Enter' : 'Ctrl-D'
159
- Planter.notify("{by}#{prompt} {xc}({bw}#{save}{xc} to save)'")
159
+ Planter.notify("{by}#{prompt} {xc}({bw}#{save}{xc} to save)'", newline: false)
160
160
  res = @gum ? read_multiline_gum(prompt) : read_mutliline_tty
161
161
 
162
162
  return @default unless res
@@ -15,6 +15,28 @@ module Planter
15
15
  snake_case.to_sym
16
16
  end
17
17
 
18
+ #
19
+ # Convert {a,b,c} to (?:a|b|c)
20
+ #
21
+ # @return [String] Converted string
22
+ #
23
+ def glob_to_rx
24
+ gsub(/\\?\{(.*?)\\?\}/) do
25
+ m = Regexp.last_match
26
+ "(?:#{m[1].split(/,/).map { |c| Regexp.escape(c) }.join('|')})"
27
+ end
28
+ end
29
+
30
+ #
31
+ # Convert a string to a regular expression by escaping special
32
+ # characters and converting wildcards (*,?) to regex wildcards
33
+ #
34
+ # @return [String] String with wildcards converted (not Regexp)
35
+ #
36
+ def to_rx
37
+ gsub(/([.()])/, '\\\\\1').gsub(/\?/, '.').gsub(/\*/, '.*?').glob_to_rx
38
+ end
39
+
18
40
  ##
19
41
  ## Convert a slug into a class name
20
42
  ##